From f2144b22107b027d7dbc68fa0c9341e33a605e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sat, 27 Oct 2018 14:51:14 +0200 Subject: [PATCH] Cleanup, editorconfig, docs and obsolete refs - Apply .editorconfig code standard across all code - Mark private fields readonly when possible - Fix obsolete warnings - Add/fix missing documentation - Normalize code and whitespace --- src/ICSharpCode.SharpZipLib/BZip2/BZip2.cs | 39 +- .../BZip2/BZip2Constants.cs | 2 +- .../BZip2/BZip2InputStream.cs | 487 +++-- .../BZip2/BZip2OutputStream.cs | 960 +++++--- .../Checksum/Adler32.cs | 39 +- .../Checksum/BZip2Crc.cs | 23 +- src/ICSharpCode.SharpZipLib/Checksum/Crc32.cs | 26 +- .../Checksum/IChecksum.cs | 3 +- .../Core/Exceptions/SharpZipBaseException.cs | 12 +- .../Exceptions/StreamDecodingException.cs | 13 +- .../Exceptions/StreamUnsupportedException.cs | 2 - .../UnexpectedEndOfStreamException.cs | 2 - .../Exceptions/ValueOutOfRangeException.cs | 19 +- .../Core/FileSystemScanner.cs | 214 +- .../Core/InvalidNameException.cs | 9 +- .../Core/NameFilter.cs | 130 +- .../Core/PathFilter.cs | 116 +- .../Core/StreamUtils.cs | 78 +- .../Core/WindowsPathUtils.cs | 26 +- .../Encryption/PkzipClassic.cs | 154 +- .../Encryption/ZipAESStream.cs | 37 +- .../Encryption/ZipAESTransform.cs | 58 +- src/ICSharpCode.SharpZipLib/GZip/GZip.cs | 9 +- .../GZip/GZipConstants.cs | 4 +- .../GZip/GzipInputStream.cs | 195 +- .../GZip/GzipOutputStream.cs | 72 +- .../Lzw/LzwConstants.cs | 3 +- .../Lzw/LzwInputStream.cs | 145 +- src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs | 420 ++-- src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs | 175 +- src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs | 157 +- .../Tar/TarException.cs | 1 - .../Tar/TarExtendedHeaderReader.cs | 30 +- src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs | 346 +-- .../Tar/TarInputStream.cs | 196 +- .../Tar/TarOutputStream.cs | 124 +- .../Zip/Compression/Deflater.cs | 211 +- .../Zip/Compression/DeflaterConstants.cs | 43 +- .../Zip/Compression/DeflaterEngine.cs | 561 +++-- .../Zip/Compression/DeflaterHuffman.cs | 330 ++- .../Zip/Compression/DeflaterPending.cs | 2 +- .../Zip/Compression/Inflater.cs | 311 ++- .../Zip/Compression/InflaterDynHeader.cs | 28 +- .../Zip/Compression/InflaterHuffmanTree.cs | 83 +- .../Zip/Compression/PendingBuffer.cs | 64 +- .../Streams/DeflaterOutputStream.cs | 159 +- .../Streams/InflaterInputStream.cs | 236 +- .../Zip/Compression/Streams/OutputWindow.cs | 77 +- .../Compression/Streams/StreamManipulator.cs | 73 +- src/ICSharpCode.SharpZipLib/Zip/FastZip.cs | 386 ++-- .../Zip/WindowsNameTransform.cs | 92 +- .../Zip/ZipConstants.cs | 52 +- src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs | 520 +++-- .../Zip/ZipEntryFactory.cs | 115 +- .../Zip/ZipException.cs | 1 - .../Zip/ZipExtraData.cs | 277 ++- src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs | 1943 +++++++++++------ .../Zip/ZipHelperStream.cs | 212 +- .../Zip/ZipInputStream.cs | 302 ++- .../Zip/ZipNameTransform.cs | 88 +- .../Zip/ZipOutputStream.cs | 392 ++-- src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs | 13 +- .../Program.cs | 11 +- .../BZip2/Bzip2Tests.cs | 39 +- .../Base/InflaterDeflaterTests.cs | 107 +- .../Checksum/ChecksumTests.cs | 49 +- .../Core/CoreTests.cs | 9 +- .../GZip/GZipTests.cs | 102 +- .../Lzw/LzwTests.cs | 14 +- .../Tar/TarTests.cs | 96 +- .../TestSupport/PerformanceTesting.cs | 17 +- .../TestSupport/RingBuffer.cs | 180 +- .../TestSupport/Streams.cs | 73 +- .../TestSupport/StringTesting.cs | 8 +- .../TestSupport/Utils.cs | 28 +- .../TestSupport/ZipTesting.cs | 7 +- .../Zip/FastZipHandling.cs | 101 +- .../Zip/GeneralHandling.cs | 217 +- .../Zip/StreamHandling.cs | 69 +- .../Zip/WindowsNameTransformHandling.cs | 55 +- .../Zip/ZipEncryptionHandling.cs | 18 +- .../Zip/ZipEntryFactoryHandling.cs | 27 +- .../Zip/ZipEntryHandling.cs | 20 +- .../Zip/ZipExtraDataHandling.cs | 112 +- .../Zip/ZipFileHandling.cs | 265 ++- .../Zip/ZipNameTransformHandling.cs | 20 +- .../Zip/ZipTests.cs | 221 +- 87 files changed, 8106 insertions(+), 4656 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2.cs index 896b3f6f5..ec6ff9402 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2.cs @@ -9,7 +9,7 @@ namespace ICSharpCode.SharpZipLib.BZip2 public static class BZip2 { /// - /// Decompress the input writing + /// Decompress the input writing /// uncompressed data to the output stream /// /// The readable stream containing data to decompress. @@ -17,17 +17,23 @@ public static class BZip2 /// Both streams are closed on completion if true. public static void Decompress(Stream inStream, Stream outStream, bool isStreamOwner) { - if (inStream == null || outStream == null) { + if (inStream == null || outStream == null) + { throw new Exception("Null Stream"); } - try { - using (BZip2InputStream bzipInput = new BZip2InputStream(inStream)) { + try + { + using (BZip2InputStream bzipInput = new BZip2InputStream(inStream)) + { bzipInput.IsStreamOwner = isStreamOwner; Core.StreamUtils.Copy(bzipInput, outStream, new byte[4096]); } - } finally { - if (isStreamOwner) { + } + finally + { + if (isStreamOwner) + { // inStream is closed by the BZip2InputStream if stream owner outStream.Dispose(); } @@ -35,32 +41,37 @@ public static void Decompress(Stream inStream, Stream outStream, bool isStreamOw } /// - /// Compress the input stream sending + /// Compress the input stream sending /// result data to output stream /// /// The readable stream to compress. /// The output stream to receive the compressed data. /// Both streams are closed on completion if true. - /// Block size acts as compression level (1 to 9) with 1 giving + /// Block size acts as compression level (1 to 9) with 1 giving /// the lowest compression and 9 the highest. public static void Compress(Stream inStream, Stream outStream, bool isStreamOwner, int level) { - if (inStream == null || outStream == null) { + if (inStream == null || outStream == null) + { throw new Exception("Null Stream"); } - try { - using (BZip2OutputStream bzipOutput = new BZip2OutputStream(outStream, level)) { + try + { + using (BZip2OutputStream bzipOutput = new BZip2OutputStream(outStream, level)) + { bzipOutput.IsStreamOwner = isStreamOwner; Core.StreamUtils.Copy(inStream, bzipOutput, new byte[4096]); } - } finally { - if (isStreamOwner) { + } + finally + { + if (isStreamOwner) + { // outStream is closed by the BZip2OutputStream if stream owner inStream.Dispose(); } } } - } } diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2Constants.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2Constants.cs index 01bf81939..146e0a093 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2Constants.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2Constants.cs @@ -66,7 +66,7 @@ internal sealed class BZip2Constants /// /// When multiplied by compression parameter (1-9) gives the block size for compression /// 9 gives the best compression but uses the most memory. - /// + /// public const int BaseBlockSize = 100000; /// diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs index 4f141de11..e639bc1f5 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs @@ -1,89 +1,93 @@ +using ICSharpCode.SharpZipLib.Checksum; using System; using System.IO; -using ICSharpCode.SharpZipLib.Checksum; namespace ICSharpCode.SharpZipLib.BZip2 { /// - /// An input stream that decompresses files in the BZip2 format + /// An input stream that decompresses files in the BZip2 format /// public class BZip2InputStream : Stream { #region Constants - const int START_BLOCK_STATE = 1; - const int RAND_PART_A_STATE = 2; - const int RAND_PART_B_STATE = 3; - const int RAND_PART_C_STATE = 4; - const int NO_RAND_PART_A_STATE = 5; - const int NO_RAND_PART_B_STATE = 6; - const int NO_RAND_PART_C_STATE = 7; - #endregion + + private const int START_BLOCK_STATE = 1; + private const int RAND_PART_A_STATE = 2; + private const int RAND_PART_B_STATE = 3; + private const int RAND_PART_C_STATE = 4; + private const int NO_RAND_PART_A_STATE = 5; + private const int NO_RAND_PART_B_STATE = 6; + private const int NO_RAND_PART_C_STATE = 7; + + #endregion Constants #region Instance Fields + /*-- index of the last char in the block, so the block size == last + 1. --*/ - int last; + private int last; /*-- index in zptr[] of original string after sorting. --*/ - int origPtr; + private int origPtr; /*-- always: in the range 0 .. 9. The current block size is 100000 * this number. --*/ - int blockSize100k; + private int blockSize100k; - bool blockRandomised; + private bool blockRandomised; - int bsBuff; - int bsLive; - IChecksum mCrc = new BZip2Crc(); + private int bsBuff; + private int bsLive; + private IChecksum mCrc = new BZip2Crc(); - bool[] inUse = new bool[256]; - int nInUse; + private bool[] inUse = new bool[256]; + private int nInUse; - byte[] seqToUnseq = new byte[256]; - byte[] unseqToSeq = new byte[256]; + private byte[] seqToUnseq = new byte[256]; + private byte[] unseqToSeq = new byte[256]; - byte[] selector = new byte[BZip2Constants.MaximumSelectors]; - byte[] selectorMtf = new byte[BZip2Constants.MaximumSelectors]; + private byte[] selector = new byte[BZip2Constants.MaximumSelectors]; + private byte[] selectorMtf = new byte[BZip2Constants.MaximumSelectors]; - int[] tt; - byte[] ll8; + private int[] tt; + private byte[] ll8; /*-- freq table collected to save a pass over the data during decompression. --*/ - int[] unzftab = new int[256]; + private int[] unzftab = new int[256]; + + private int[][] limit = new int[BZip2Constants.GroupCount][]; + private int[][] baseArray = new int[BZip2Constants.GroupCount][]; + private int[][] perm = new int[BZip2Constants.GroupCount][]; + private int[] minLens = new int[BZip2Constants.GroupCount]; - int[][] limit = new int[BZip2Constants.GroupCount][]; - int[][] baseArray = new int[BZip2Constants.GroupCount][]; - int[][] perm = new int[BZip2Constants.GroupCount][]; - int[] minLens = new int[BZip2Constants.GroupCount]; + private readonly Stream baseStream; + private bool streamEnd; - readonly Stream baseStream; - bool streamEnd; + private int currentChar = -1; - int currentChar = -1; + private int currentState = START_BLOCK_STATE; - int currentState = START_BLOCK_STATE; + private int storedBlockCRC, storedCombinedCRC; + private int computedBlockCRC; + private uint computedCombinedCRC; - int storedBlockCRC, storedCombinedCRC; - int computedBlockCRC; - uint computedCombinedCRC; + private int count, chPrev, ch2; + private int tPos; + private int rNToGo; + private int rTPos; + private int i2, j2; + private byte z; - int count, chPrev, ch2; - int tPos; - int rNToGo; - int rTPos; - int i2, j2; - byte z; - #endregion + #endregion Instance Fields /// /// Construct instance for reading from stream @@ -94,7 +98,8 @@ public BZip2InputStream(Stream stream) if (stream == null) throw new ArgumentNullException(nameof(stream)); // init arrays - for (int i = 0; i < BZip2Constants.GroupCount; ++i) { + for (int i = 0; i < BZip2Constants.GroupCount; ++i) + { limit[i] = new int[BZip2Constants.MaximumAlphaSize]; baseArray[i] = new int[BZip2Constants.MaximumAlphaSize]; perm[i] = new int[BZip2Constants.MaximumAlphaSize]; @@ -115,11 +120,14 @@ public BZip2InputStream(Stream stream) public bool IsStreamOwner { get; set; } = true; #region Stream Overrides + /// /// Gets a value indicating if the stream supports reading /// - public override bool CanRead { - get { + public override bool CanRead + { + get + { return baseStream.CanRead; } } @@ -127,8 +135,10 @@ public override bool CanRead { /// /// Gets a value indicating whether the current stream supports seeking. /// - public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return false; } } @@ -137,8 +147,10 @@ public override bool CanSeek { /// Gets a value indicating whether the current stream supports writing. /// This property always returns false /// - public override bool CanWrite { - get { + public override bool CanWrite + { + get + { return false; } } @@ -146,8 +158,10 @@ public override bool CanWrite { /// /// Gets the length in bytes of the stream. /// - public override long Length { - get { + public override long Length + { + get + { return baseStream.Length; } } @@ -157,11 +171,14 @@ public override long Length { /// Setting the position is not supported and will throw a NotSupportException. /// /// Any attempt to set the position. - public override long Position { - get { + public override long Position + { + get + { return baseStream.Position; } - set { + set + { throw new NotSupportedException("BZip2InputStream position cannot be set"); } } @@ -228,18 +245,21 @@ public override void WriteByte(byte value) /// Offset in array to begin storing data /// The maximum number of bytes to read /// The total number of bytes read into the buffer. This might be less - /// than the number of bytes requested if that number of bytes are not + /// than the number of bytes requested if that number of bytes are not /// currently available or zero if the end of the stream is reached. /// public override int Read(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - for (int i = 0; i < count; ++i) { + for (int i = 0; i < count; ++i) + { int rb = ReadByte(); - if (rb == -1) { + if (rb == -1) + { return i; } buffer[offset + i] = (byte)rb; @@ -252,34 +272,42 @@ public override int Read(byte[] buffer, int offset, int count) /// protected override void Dispose(bool disposing) { - if (disposing && IsStreamOwner) { + if (disposing && IsStreamOwner) + { baseStream.Dispose(); } } + /// /// Read a byte from stream advancing position /// /// byte read or -1 on end of stream public override int ReadByte() { - if (streamEnd) { + if (streamEnd) + { return -1; // ok } int retChar = currentChar; - switch (currentState) { + switch (currentState) + { case RAND_PART_B_STATE: SetupRandPartB(); break; + case RAND_PART_C_STATE: SetupRandPartC(); break; + case NO_RAND_PART_B_STATE: SetupNoRandPartB(); break; + case NO_RAND_PART_C_STATE: SetupNoRandPartC(); break; + case START_BLOCK_STATE: case NO_RAND_PART_A_STATE: case RAND_PART_A_STATE: @@ -288,13 +316,15 @@ public override int ReadByte() return retChar; } - #endregion + #endregion Stream Overrides - void MakeMaps() + private void MakeMaps() { nInUse = 0; - for (int i = 0; i < 256; ++i) { - if (inUse[i]) { + for (int i = 0; i < 256; ++i) + { + if (inUse[i]) + { seqToUnseq[nInUse] = (byte)i; unseqToSeq[i] = (byte)nInUse; nInUse++; @@ -302,7 +332,7 @@ void MakeMaps() } } - void Initialize() + private void Initialize() { char magic1 = BsGetUChar(); char magic2 = BsGetUChar(); @@ -310,7 +340,8 @@ void Initialize() char magic3 = BsGetUChar(); char magic4 = BsGetUChar(); - if (magic1 != 'B' || magic2 != 'Z' || magic3 != 'h' || magic4 < '1' || magic4 > '9') { + if (magic1 != 'B' || magic2 != 'Z' || magic3 != 'h' || magic4 < '1' || magic4 > '9') + { streamEnd = true; return; } @@ -319,7 +350,7 @@ void Initialize() computedCombinedCRC = 0; } - void InitBlock() + private void InitBlock() { char magic1 = BsGetUChar(); char magic2 = BsGetUChar(); @@ -328,12 +359,14 @@ void InitBlock() char magic5 = BsGetUChar(); char magic6 = BsGetUChar(); - if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) { + if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) + { Complete(); return; } - if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) { + if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) + { BadBlockHeader(); streamEnd = true; return; @@ -349,12 +382,13 @@ void InitBlock() currentState = START_BLOCK_STATE; } - void EndBlock() + private void EndBlock() { computedBlockCRC = (int)mCrc.Value; // -- A bad CRC is considered a fatal error. -- - if (storedBlockCRC != computedBlockCRC) { + if (storedBlockCRC != computedBlockCRC) + { CrcError(); } @@ -363,27 +397,32 @@ void EndBlock() computedCombinedCRC = computedCombinedCRC ^ (uint)computedBlockCRC; } - void Complete() + private void Complete() { storedCombinedCRC = BsGetInt32(); - if (storedCombinedCRC != (int)computedCombinedCRC) { + if (storedCombinedCRC != (int)computedCombinedCRC) + { CrcError(); } streamEnd = true; } - void FillBuffer() + private void FillBuffer() { int thech = 0; - try { + try + { thech = baseStream.ReadByte(); - } catch (Exception) { + } + catch (Exception) + { CompressedStreamEOF(); } - if (thech == -1) { + if (thech == -1) + { CompressedStreamEOF(); } @@ -391,9 +430,10 @@ void FillBuffer() bsLive += 8; } - int BsR(int n) + private int BsR(int n) { - while (bsLive < n) { + while (bsLive < n) + { FillBuffer(); } @@ -402,17 +442,17 @@ int BsR(int n) return v; } - char BsGetUChar() + private char BsGetUChar() { return (char)BsR(8); } - int BsGetIntVS(int numBits) + private int BsGetIntVS(int numBits) { return BsR(numBits); } - int BsGetInt32() + private int BsGetInt32() { int result = BsR(8); result = (result << 8) | BsR(8); @@ -421,27 +461,35 @@ int BsGetInt32() return result; } - void RecvDecodingTables() + private void RecvDecodingTables() { char[][] len = new char[BZip2Constants.GroupCount][]; - for (int i = 0; i < BZip2Constants.GroupCount; ++i) { + for (int i = 0; i < BZip2Constants.GroupCount; ++i) + { len[i] = new char[BZip2Constants.MaximumAlphaSize]; } bool[] inUse16 = new bool[16]; //--- Receive the mapping table --- - for (int i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) + { inUse16[i] = (BsR(1) == 1); } - for (int i = 0; i < 16; i++) { - if (inUse16[i]) { - for (int j = 0; j < 16; j++) { + for (int i = 0; i < 16; i++) + { + if (inUse16[i]) + { + for (int j = 0; j < 16; j++) + { inUse[i * 16 + j] = (BsR(1) == 1); } - } else { - for (int j = 0; j < 16; j++) { + } + else + { + for (int j = 0; j < 16; j++) + { inUse[i * 16 + j] = false; } } @@ -454,9 +502,11 @@ void RecvDecodingTables() int nGroups = BsR(3); int nSelectors = BsR(15); - for (int i = 0; i < nSelectors; i++) { + for (int i = 0; i < nSelectors; i++) + { int j = 0; - while (BsR(1) == 1) { + while (BsR(1) == 1) + { j++; } selectorMtf[i] = (byte)j; @@ -464,14 +514,17 @@ void RecvDecodingTables() //--- Undo the MTF values for the selectors. --- byte[] pos = new byte[BZip2Constants.GroupCount]; - for (int v = 0; v < nGroups; v++) { + for (int v = 0; v < nGroups; v++) + { pos[v] = (byte)v; } - for (int i = 0; i < nSelectors; i++) { + for (int i = 0; i < nSelectors; i++) + { int v = selectorMtf[i]; byte tmp = pos[v]; - while (v > 0) { + while (v > 0) + { pos[v] = pos[v - 1]; v--; } @@ -480,13 +533,19 @@ void RecvDecodingTables() } //--- Now the coding tables --- - for (int t = 0; t < nGroups; t++) { + for (int t = 0; t < nGroups; t++) + { int curr = BsR(5); - for (int i = 0; i < alphaSize; i++) { - while (BsR(1) == 1) { - if (BsR(1) == 0) { + for (int i = 0; i < alphaSize; i++) + { + while (BsR(1) == 1) + { + if (BsR(1) == 0) + { curr++; - } else { + } + else + { curr--; } } @@ -495,10 +554,12 @@ void RecvDecodingTables() } //--- Create the Huffman decoding tables --- - for (int t = 0; t < nGroups; t++) { + for (int t = 0; t < nGroups; t++) + { int minLen = 32; int maxLen = 0; - for (int i = 0; i < alphaSize; i++) { + for (int i = 0; i < alphaSize; i++) + { maxLen = Math.Max(maxLen, len[t][i]); minLen = Math.Min(minLen, len[t][i]); } @@ -507,7 +568,7 @@ void RecvDecodingTables() } } - void GetAndMoveToFrontDecode() + private void GetAndMoveToFrontDecode() { byte[] yy = new byte[256]; int nextSym; @@ -526,17 +587,20 @@ Setting up the unzftab entries here is not strictly in a separate pass, and so saves a block's worth of cache misses. --*/ - for (int i = 0; i <= 255; i++) { + for (int i = 0; i <= 255; i++) + { unzftab[i] = 0; } - for (int i = 0; i <= 255; i++) { + for (int i = 0; i <= 255; i++) + { yy[i] = (byte)i; } last = -1; - if (groupPos == 0) { + if (groupPos == 0) + { groupNo++; groupPos = BZip2Constants.GroupSize; } @@ -547,41 +611,53 @@ cache misses. int zvec = BsR(zn); int zj; - while (zvec > limit[zt][zn]) { - if (zn > 20) { // the longest code + while (zvec > limit[zt][zn]) + { + if (zn > 20) + { // the longest code throw new BZip2Exception("Bzip data error"); } zn++; - while (bsLive < 1) { + while (bsLive < 1) + { FillBuffer(); } zj = (bsBuff >> (bsLive - 1)) & 1; bsLive--; zvec = (zvec << 1) | zj; } - if (zvec - baseArray[zt][zn] < 0 || zvec - baseArray[zt][zn] >= BZip2Constants.MaximumAlphaSize) { + if (zvec - baseArray[zt][zn] < 0 || zvec - baseArray[zt][zn] >= BZip2Constants.MaximumAlphaSize) + { throw new BZip2Exception("Bzip data error"); } nextSym = perm[zt][zvec - baseArray[zt][zn]]; - while (true) { - if (nextSym == EOB) { + while (true) + { + if (nextSym == EOB) + { break; } - if (nextSym == BZip2Constants.RunA || nextSym == BZip2Constants.RunB) { + if (nextSym == BZip2Constants.RunA || nextSym == BZip2Constants.RunB) + { int s = -1; int n = 1; - do { - if (nextSym == BZip2Constants.RunA) { + do + { + if (nextSym == BZip2Constants.RunA) + { s += (0 + 1) * n; - } else if (nextSym == BZip2Constants.RunB) { + } + else if (nextSym == BZip2Constants.RunB) + { s += (1 + 1) * n; } n <<= 1; - if (groupPos == 0) { + if (groupPos == 0) + { groupNo++; groupPos = BZip2Constants.GroupSize; } @@ -592,9 +668,11 @@ cache misses. zn = minLens[zt]; zvec = BsR(zn); - while (zvec > limit[zt][zn]) { + while (zvec > limit[zt][zn]) + { zn++; - while (bsLive < 1) { + while (bsLive < 1) + { FillBuffer(); } zj = (bsBuff >> (bsLive - 1)) & 1; @@ -608,19 +686,24 @@ cache misses. byte ch = seqToUnseq[yy[0]]; unzftab[ch] += s; - while (s > 0) { + while (s > 0) + { last++; ll8[last] = ch; s--; } - if (last >= limitLast) { + if (last >= limitLast) + { BlockOverrun(); } continue; - } else { + } + else + { last++; - if (last >= limitLast) { + if (last >= limitLast) + { BlockOverrun(); } @@ -628,12 +711,14 @@ cache misses. unzftab[seqToUnseq[tmp]]++; ll8[last] = seqToUnseq[tmp]; - for (int j = nextSym - 1; j > 0; --j) { + for (int j = nextSym - 1; j > 0; --j) + { yy[j] = yy[j - 1]; } yy[0] = tmp; - if (groupPos == 0) { + if (groupPos == 0) + { groupNo++; groupPos = BZip2Constants.GroupSize; } @@ -642,9 +727,11 @@ cache misses. zt = selector[groupNo]; zn = minLens[zt]; zvec = BsR(zn); - while (zvec > limit[zt][zn]) { + while (zvec > limit[zt][zn]) + { zn++; - while (bsLive < 1) { + while (bsLive < 1) + { FillBuffer(); } zj = (bsBuff >> (bsLive - 1)) & 1; @@ -657,18 +744,20 @@ cache misses. } } - void SetupBlock() + private void SetupBlock() { int[] cftab = new int[257]; cftab[0] = 0; Array.Copy(unzftab, 0, cftab, 1, 256); - for (int i = 1; i <= 256; i++) { + for (int i = 1; i <= 256; i++) + { cftab[i] += cftab[i - 1]; } - for (int i = 0; i <= last; i++) { + for (int i = 0; i <= last; i++) + { byte ch = ll8[i]; tt[cftab[ch]] = i; cftab[ch]++; @@ -682,25 +771,31 @@ void SetupBlock() i2 = 0; ch2 = 256; /*-- not a char and not EOF --*/ - if (blockRandomised) { + if (blockRandomised) + { rNToGo = 0; rTPos = 0; SetupRandPartA(); - } else { + } + else + { SetupNoRandPartA(); } } - void SetupRandPartA() + private void SetupRandPartA() { - if (i2 <= last) { + if (i2 <= last) + { chPrev = ch2; ch2 = ll8[tPos]; tPos = tt[tPos]; - if (rNToGo == 0) { + if (rNToGo == 0) + { rNToGo = BZip2Constants.RandomNumbers[rTPos]; rTPos++; - if (rTPos == 512) { + if (rTPos == 512) + { rTPos = 0; } } @@ -711,16 +806,19 @@ void SetupRandPartA() currentChar = ch2; currentState = RAND_PART_B_STATE; mCrc.Update(ch2); - } else { + } + else + { EndBlock(); InitBlock(); SetupBlock(); } } - void SetupNoRandPartA() + private void SetupNoRandPartA() { - if (i2 <= last) { + if (i2 <= last) + { chPrev = ch2; ch2 = ll8[tPos]; tPos = tt[tPos]; @@ -729,28 +827,36 @@ void SetupNoRandPartA() currentChar = ch2; currentState = NO_RAND_PART_B_STATE; mCrc.Update(ch2); - } else { + } + else + { EndBlock(); InitBlock(); SetupBlock(); } } - void SetupRandPartB() + private void SetupRandPartB() { - if (ch2 != chPrev) { + if (ch2 != chPrev) + { currentState = RAND_PART_A_STATE; count = 1; SetupRandPartA(); - } else { + } + else + { count++; - if (count >= 4) { + if (count >= 4) + { z = ll8[tPos]; tPos = tt[tPos]; - if (rNToGo == 0) { + if (rNToGo == 0) + { rNToGo = BZip2Constants.RandomNumbers[rTPos]; rTPos++; - if (rTPos == 512) { + if (rTPos == 512) + { rTPos = 0; } } @@ -759,20 +865,25 @@ void SetupRandPartB() j2 = 0; currentState = RAND_PART_C_STATE; SetupRandPartC(); - } else { + } + else + { currentState = RAND_PART_A_STATE; SetupRandPartA(); } } } - void SetupRandPartC() + private void SetupRandPartC() { - if (j2 < (int)z) { + if (j2 < (int)z) + { currentChar = ch2; mCrc.Update(ch2); j2++; - } else { + } + else + { currentState = RAND_PART_A_STATE; i2++; count = 0; @@ -780,34 +891,43 @@ void SetupRandPartC() } } - void SetupNoRandPartB() + private void SetupNoRandPartB() { - if (ch2 != chPrev) { + if (ch2 != chPrev) + { currentState = NO_RAND_PART_A_STATE; count = 1; SetupNoRandPartA(); - } else { + } + else + { count++; - if (count >= 4) { + if (count >= 4) + { z = ll8[tPos]; tPos = tt[tPos]; currentState = NO_RAND_PART_C_STATE; j2 = 0; SetupNoRandPartC(); - } else { + } + else + { currentState = NO_RAND_PART_A_STATE; SetupNoRandPartA(); } } } - void SetupNoRandPartC() + private void SetupNoRandPartC() { - if (j2 < (int)z) { + if (j2 < (int)z) + { currentChar = ch2; mCrc.Update(ch2); j2++; - } else { + } + else + { currentState = NO_RAND_PART_A_STATE; i2++; count = 0; @@ -815,15 +935,17 @@ void SetupNoRandPartC() } } - void SetDecompressStructureSizes(int newSize100k) + private void SetDecompressStructureSizes(int newSize100k) { - if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k && blockSize100k <= 9)) { + if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k && blockSize100k <= 9)) + { throw new BZip2Exception("Invalid block size"); } blockSize100k = newSize100k; - if (newSize100k == 0) { + if (newSize100k == 0) + { return; } @@ -832,64 +954,73 @@ void SetDecompressStructureSizes(int newSize100k) tt = new int[n]; } - static void CompressedStreamEOF() + private static void CompressedStreamEOF() { throw new EndOfStreamException("BZip2 input stream end of compressed stream"); } - static void BlockOverrun() + private static void BlockOverrun() { throw new BZip2Exception("BZip2 input stream block overrun"); } - static void BadBlockHeader() + private static void BadBlockHeader() { throw new BZip2Exception("BZip2 input stream bad block header"); } - static void CrcError() + private static void CrcError() { throw new BZip2Exception("BZip2 input stream crc error"); } - static void HbCreateDecodeTables(int[] limit, int[] baseArray, int[] perm, char[] length, int minLen, int maxLen, int alphaSize) + private static void HbCreateDecodeTables(int[] limit, int[] baseArray, int[] perm, char[] length, int minLen, int maxLen, int alphaSize) { int pp = 0; - for (int i = minLen; i <= maxLen; ++i) { - for (int j = 0; j < alphaSize; ++j) { - if (length[j] == i) { + for (int i = minLen; i <= maxLen; ++i) + { + for (int j = 0; j < alphaSize; ++j) + { + if (length[j] == i) + { perm[pp] = j; ++pp; } } } - for (int i = 0; i < BZip2Constants.MaximumCodeLength; i++) { + for (int i = 0; i < BZip2Constants.MaximumCodeLength; i++) + { baseArray[i] = 0; } - for (int i = 0; i < alphaSize; i++) { + for (int i = 0; i < alphaSize; i++) + { ++baseArray[length[i] + 1]; } - for (int i = 1; i < BZip2Constants.MaximumCodeLength; i++) { + for (int i = 1; i < BZip2Constants.MaximumCodeLength; i++) + { baseArray[i] += baseArray[i - 1]; } - for (int i = 0; i < BZip2Constants.MaximumCodeLength; i++) { + for (int i = 0; i < BZip2Constants.MaximumCodeLength; i++) + { limit[i] = 0; } int vec = 0; - for (int i = minLen; i <= maxLen; i++) { + for (int i = minLen; i <= maxLen; i++) + { vec += (baseArray[i + 1] - baseArray[i]); limit[i] = vec - 1; vec <<= 1; } - for (int i = minLen + 1; i <= maxLen; i++) { + for (int i = minLen + 1; i <= maxLen; i++) + { baseArray[i] = ((limit[i - 1] + 1) << 1) - baseArray[i]; } } diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs index 008015052..f331ec657 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs @@ -1,22 +1,23 @@ +using ICSharpCode.SharpZipLib.Checksum; using System; using System.IO; -using ICSharpCode.SharpZipLib.Checksum; namespace ICSharpCode.SharpZipLib.BZip2 { /// - /// An output stream that compresses into the BZip2 format + /// An output stream that compresses into the BZip2 format /// including file header chars into another stream. /// public class BZip2OutputStream : Stream { #region Constants - const int SETMASK = (1 << 21); - const int CLEARMASK = (~SETMASK); - const int GREATER_ICOST = 15; - const int LESSER_ICOST = 0; - const int SMALL_THRESH = 20; - const int DEPTH_THRESH = 10; + + private const int SETMASK = (1 << 21); + private const int CLEARMASK = (~SETMASK); + private const int GREATER_ICOST = 15; + private const int LESSER_ICOST = 0; + private const int SMALL_THRESH = 20; + private const int DEPTH_THRESH = 10; /*-- If you are ever unlucky/improbable enough @@ -26,7 +27,7 @@ again. In practice I have never seen the stack go above 27 elems, so the following limit seems very generous. --*/ - const int QSORT_STACK_SIZE = 1000; + private const int QSORT_STACK_SIZE = 1000; /*-- Knuth's increments seem to work better @@ -34,75 +35,79 @@ than Incerpi-Sedgewick here. Possibly because the number of elems to sort is usually small, typically <= 20. --*/ - readonly int[] increments = { + + private readonly int[] increments = { 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484 }; - #endregion + + #endregion Constants #region Instance Fields + /*-- index of the last char in the block, so the block size == last + 1. --*/ - int last; + private int last; /*-- index in zptr[] of original string after sorting. --*/ - int origPtr; + private int origPtr; /*-- always: in the range 0 .. 9. The current block size is 100000 * this number. --*/ - int blockSize100k; + private int blockSize100k; - bool blockRandomised; + private bool blockRandomised; - int bytesOut; - int bsBuff; - int bsLive; - IChecksum mCrc = new BZip2Crc(); + private int bytesOut; + private int bsBuff; + private int bsLive; + private IChecksum mCrc = new BZip2Crc(); - bool[] inUse = new bool[256]; - int nInUse; + private bool[] inUse = new bool[256]; + private int nInUse; - char[] seqToUnseq = new char[256]; - char[] unseqToSeq = new char[256]; + private char[] seqToUnseq = new char[256]; + private char[] unseqToSeq = new char[256]; - char[] selector = new char[BZip2Constants.MaximumSelectors]; - char[] selectorMtf = new char[BZip2Constants.MaximumSelectors]; + private char[] selector = new char[BZip2Constants.MaximumSelectors]; + private char[] selectorMtf = new char[BZip2Constants.MaximumSelectors]; - byte[] block; - int[] quadrant; - int[] zptr; - short[] szptr; - int[] ftab; + private byte[] block; + private int[] quadrant; + private int[] zptr; + private short[] szptr; + private int[] ftab; - int nMTF; + private int nMTF; - int[] mtfFreq = new int[BZip2Constants.MaximumAlphaSize]; + private int[] mtfFreq = new int[BZip2Constants.MaximumAlphaSize]; /* * Used when sorting. If too many long comparisons * happen, we stop sorting, randomise the block * slightly, and try again. */ - int workFactor; - int workDone; - int workLimit; - bool firstAttempt; - int nBlocksRandomised; - - int currentChar = -1; - int runLength; - uint blockCRC, combinedCRC; - int allowableBlockSize; - readonly Stream baseStream; - bool disposed_; - #endregion + private int workFactor; + private int workDone; + private int workLimit; + private bool firstAttempt; + private int nBlocksRandomised; + + private int currentChar = -1; + private int runLength; + private uint blockCRC, combinedCRC; + private int allowableBlockSize; + private readonly Stream baseStream; + private bool disposed_; + + #endregion Instance Fields /// /// Construct a default output stream with maximum block size @@ -113,13 +118,13 @@ public BZip2OutputStream(Stream stream) : this(stream, 9) } /// - /// Initialise a new instance of the + /// Initialise a new instance of the /// for the specified stream, using the given blocksize. /// /// The stream to write compressed data to. /// The block size to use. /// - /// Valid block sizes are in the range 1..9, with 1 giving + /// Valid block sizes are in the range 1..9, with 1 giving /// the lowest compression and 9 the highest. /// public BZip2OutputStream(Stream stream, int blockSize) @@ -133,11 +138,13 @@ public BZip2OutputStream(Stream stream, int blockSize) bytesOut = 0; workFactor = 50; - if (blockSize > 9) { + if (blockSize > 9) + { blockSize = 9; } - if (blockSize < 1) { + if (blockSize < 1) + { blockSize = 1; } blockSize100k = blockSize; @@ -147,7 +154,7 @@ public BZip2OutputStream(Stream stream, int blockSize) } /// - /// Ensures that resources are freed and other cleanup operations + /// Ensures that resources are freed and other cleanup operations /// are performed when the garbage collector reclaims the BZip2OutputStream. /// ~BZip2OutputStream() @@ -257,7 +264,7 @@ public override int ReadByte() /// The offset in the buffer to start storing data at. /// The maximum number of bytes to read. /// The total number of bytes read. This might be less than the number of bytes - /// requested if that number of bytes are not currently available, or zero + /// requested if that number of bytes are not currently available, or zero /// if the end of the stream is reached. public override int Read(byte[] buffer, int offset, int count) { @@ -272,23 +279,28 @@ public override int Read(byte[] buffer, int offset, int count) /// The number of bytes to write. public override void Write(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset)); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count)); } - if (buffer.Length - offset < count) { + if (buffer.Length - offset < count) + { throw new ArgumentException("Offset/count out of range"); } - for (int i = 0; i < count; ++i) { + for (int i = 0; i < count; ++i) + { WriteByte(buffer[offset + i]); } } @@ -300,30 +312,39 @@ public override void Write(byte[] buffer, int offset, int count) public override void WriteByte(byte value) { int b = (256 + value) % 256; - if (currentChar != -1) { - if (currentChar == b) { + if (currentChar != -1) + { + if (currentChar == b) + { runLength++; - if (runLength > 254) { + if (runLength > 254) + { WriteRun(); currentChar = -1; runLength = 0; } - } else { + } + else + { WriteRun(); runLength = 1; currentChar = b; } - } else { + } + else + { currentChar = b; runLength++; } } - void MakeMaps() + private void MakeMaps() { nInUse = 0; - for (int i = 0; i < 256; i++) { - if (inUse[i]) { + for (int i = 0; i < 256; i++) + { + if (inUse[i]) + { seqToUnseq[nInUse] = (char)i; unseqToSeq[i] = (char)nInUse; nInUse++; @@ -334,48 +355,56 @@ void MakeMaps() /// /// Get the number of bytes written to output. /// - void WriteRun() + private void WriteRun() { - if (last < allowableBlockSize) { + if (last < allowableBlockSize) + { inUse[currentChar] = true; - for (int i = 0; i < runLength; i++) { + for (int i = 0; i < runLength; i++) + { mCrc.Update(currentChar); } - switch (runLength) { - case 1: - last++; - block[last + 1] = (byte)currentChar; - break; - case 2: - last++; - block[last + 1] = (byte)currentChar; - last++; - block[last + 1] = (byte)currentChar; - break; - case 3: - last++; - block[last + 1] = (byte)currentChar; - last++; - block[last + 1] = (byte)currentChar; - last++; - block[last + 1] = (byte)currentChar; - break; - default: - inUse[runLength - 4] = true; - last++; - block[last + 1] = (byte)currentChar; - last++; - block[last + 1] = (byte)currentChar; - last++; - block[last + 1] = (byte)currentChar; - last++; - block[last + 1] = (byte)currentChar; - last++; - block[last + 1] = (byte)(runLength - 4); - break; + switch (runLength) + { + case 1: + last++; + block[last + 1] = (byte)currentChar; + break; + + case 2: + last++; + block[last + 1] = (byte)currentChar; + last++; + block[last + 1] = (byte)currentChar; + break; + + case 3: + last++; + block[last + 1] = (byte)currentChar; + last++; + block[last + 1] = (byte)currentChar; + last++; + block[last + 1] = (byte)currentChar; + break; + + default: + inUse[runLength - 4] = true; + last++; + block[last + 1] = (byte)currentChar; + last++; + block[last + 1] = (byte)currentChar; + last++; + block[last + 1] = (byte)currentChar; + last++; + block[last + 1] = (byte)currentChar; + last++; + block[last + 1] = (byte)(runLength - 4); + break; } - } else { + } + else + { EndBlock(); InitBlock(); WriteRun(); @@ -396,13 +425,17 @@ public int BytesWritten /// true to release both managed and unmanaged resources; false to release only unmanaged resources. override protected void Dispose(bool disposing) { - try { - try { + try + { + try + { base.Dispose(disposing); - if (!disposed_) { + if (!disposed_) + { disposed_ = true; - if (runLength > 0) { + if (runLength > 0) + { WriteRun(); } @@ -411,26 +444,32 @@ override protected void Dispose(bool disposing) EndCompression(); Flush(); } - } finally { - if (disposing) { - if (IsStreamOwner) { + } + finally + { + if (disposing) + { + if (IsStreamOwner) + { baseStream.Dispose(); } } } - } catch { + } + catch + { } } /// /// Flush output buffers - /// + /// public override void Flush() { baseStream.Flush(); } - void Initialize() + private void Initialize() { bytesOut = 0; nBlocksRandomised = 0; @@ -448,12 +487,13 @@ followed by a digit indicating blockSize100k. combinedCRC = 0; } - void InitBlock() + private void InitBlock() { mCrc.Reset(); last = -1; - for (int i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) + { inUse[i] = false; } @@ -461,9 +501,10 @@ void InitBlock() allowableBlockSize = BZip2Constants.BaseBlockSize * blockSize100k - 20; } - void EndBlock() + private void EndBlock() { - if (last < 0) { // dont do anything for empty files, (makes empty files compatible with original Bzip) + if (last < 0) + { // dont do anything for empty files, (makes empty files compatible with original Bzip) return; } @@ -495,15 +536,19 @@ damaged files. BsPutUChar(0x59); /*-- Now the block's CRC, so it is in a known place. --*/ - unchecked { + unchecked + { BsPutint((int)blockCRC); } /*-- Now a single bit indicating randomisation. --*/ - if (blockRandomised) { + if (blockRandomised) + { BsW(1, 1); nBlocksRandomised++; - } else { + } + else + { BsW(1, 0); } @@ -511,7 +556,7 @@ damaged files. MoveToFrontCodeAndSend(); } - void EndCompression() + private void EndCompression() { /*-- Now another magic 48-bit number, 0x177245385090, to @@ -527,16 +572,18 @@ void EndCompression() BsPutUChar(0x50); BsPutUChar(0x90); - unchecked { + unchecked + { BsPutint((int)combinedCRC); } BsFinishedWithStream(); } - void BsFinishedWithStream() + private void BsFinishedWithStream() { - while (bsLive > 0) { + while (bsLive > 0) + { int ch = (bsBuff >> 24); baseStream.WriteByte((byte)ch); // write 8-bit bsBuff <<= 8; @@ -545,9 +592,10 @@ void BsFinishedWithStream() } } - void BsW(int n, int v) + private void BsW(int n, int v) { - while (bsLive >= 8) { + while (bsLive >= 8) + { int ch = (bsBuff >> 24); unchecked { baseStream.WriteByte((byte)ch); } // write 8-bit bsBuff <<= 8; @@ -558,12 +606,12 @@ void BsW(int n, int v) bsLive += n; } - void BsPutUChar(int c) + private void BsPutUChar(int c) { BsW(8, c); } - void BsPutint(int u) + private void BsPutint(int u) { BsW(8, (u >> 24) & 0xFF); BsW(8, (u >> 16) & 0xFF); @@ -571,15 +619,16 @@ void BsPutint(int u) BsW(8, u & 0xFF); } - void BsPutIntVS(int numBits, int c) + private void BsPutIntVS(int numBits, int c) { BsW(numBits, c); } - void SendMTFValues() + private void SendMTFValues() { char[][] len = new char[BZip2Constants.GroupCount][]; - for (int i = 0; i < BZip2Constants.GroupCount; ++i) { + for (int i = 0; i < BZip2Constants.GroupCount; ++i) + { len[i] = new char[BZip2Constants.MaximumAlphaSize]; } @@ -588,26 +637,38 @@ void SendMTFValues() int nGroups; alphaSize = nInUse + 2; - for (int t = 0; t < BZip2Constants.GroupCount; t++) { - for (int v = 0; v < alphaSize; v++) { + for (int t = 0; t < BZip2Constants.GroupCount; t++) + { + for (int v = 0; v < alphaSize; v++) + { len[t][v] = (char)GREATER_ICOST; } } /*--- Decide how many coding tables to use ---*/ - if (nMTF <= 0) { + if (nMTF <= 0) + { Panic(); } - if (nMTF < 200) { + if (nMTF < 200) + { nGroups = 2; - } else if (nMTF < 600) { + } + else if (nMTF < 600) + { nGroups = 3; - } else if (nMTF < 1200) { + } + else if (nMTF < 1200) + { nGroups = 4; - } else if (nMTF < 2400) { + } + else if (nMTF < 2400) + { nGroups = 5; - } else { + } + else + { nGroups = 6; } @@ -615,24 +676,31 @@ void SendMTFValues() int nPart = nGroups; int remF = nMTF; gs = 0; - while (nPart > 0) { + while (nPart > 0) + { int tFreq = remF / nPart; int aFreq = 0; ge = gs - 1; - while (aFreq < tFreq && ge < alphaSize - 1) { + while (aFreq < tFreq && ge < alphaSize - 1) + { ge++; aFreq += mtfFreq[ge]; } - if (ge > gs && nPart != nGroups && nPart != 1 && ((nGroups - nPart) % 2 == 1)) { + if (ge > gs && nPart != nGroups && nPart != 1 && ((nGroups - nPart) % 2 == 1)) + { aFreq -= mtfFreq[ge]; ge--; } - for (int v = 0; v < alphaSize; v++) { - if (v >= gs && v <= ge) { + for (int v = 0; v < alphaSize; v++) + { + if (v >= gs && v <= ge) + { len[nPart - 1][v] = (char)LESSER_ICOST; - } else { + } + else + { len[nPart - 1][v] = (char)GREATER_ICOST; } } @@ -643,7 +711,8 @@ void SendMTFValues() } int[][] rfreq = new int[BZip2Constants.GroupCount][]; - for (int i = 0; i < BZip2Constants.GroupCount; ++i) { + for (int i = 0; i < BZip2Constants.GroupCount; ++i) + { rfreq[i] = new int[BZip2Constants.MaximumAlphaSize]; } @@ -652,13 +721,17 @@ void SendMTFValues() /*--- Iterate up to N_ITERS times to improve the tables. ---*/ - for (iter = 0; iter < BZip2Constants.NumberOfIterations; ++iter) { - for (int t = 0; t < nGroups; ++t) { + for (iter = 0; iter < BZip2Constants.NumberOfIterations; ++iter) + { + for (int t = 0; t < nGroups; ++t) + { fave[t] = 0; } - for (int t = 0; t < nGroups; ++t) { - for (int v = 0; v < alphaSize; ++v) { + for (int t = 0; t < nGroups; ++t) + { + for (int v = 0; v < alphaSize; ++v) + { rfreq[t][v] = 0; } } @@ -666,13 +739,16 @@ Iterate up to N_ITERS times to improve the tables. nSelectors = 0; totc = 0; gs = 0; - while (true) { + while (true) + { /*--- Set group start & end marks. --*/ - if (gs >= nMTF) { + if (gs >= nMTF) + { break; } ge = gs + BZip2Constants.GroupSize - 1; - if (ge >= nMTF) { + if (ge >= nMTF) + { ge = nMTF - 1; } @@ -680,14 +756,17 @@ Iterate up to N_ITERS times to improve the tables. Calculate the cost of this group as coded by each of the coding tables. --*/ - for (int t = 0; t < nGroups; t++) { + for (int t = 0; t < nGroups; t++) + { cost[t] = 0; } - if (nGroups == 6) { + if (nGroups == 6) + { short cost0, cost1, cost2, cost3, cost4, cost5; cost0 = cost1 = cost2 = cost3 = cost4 = cost5 = 0; - for (int i = gs; i <= ge; ++i) { + for (int i = gs; i <= ge; ++i) + { short icv = szptr[i]; cost0 += (short)len[0][icv]; cost1 += (short)len[1][icv]; @@ -702,10 +781,14 @@ by each of the coding tables. cost[3] = cost3; cost[4] = cost4; cost[5] = cost5; - } else { - for (int i = gs; i <= ge; ++i) { + } + else + { + for (int i = gs; i <= ge; ++i) + { short icv = szptr[i]; - for (int t = 0; t < nGroups; t++) { + for (int t = 0; t < nGroups; t++) + { cost[t] += (short)len[t][icv]; } } @@ -717,8 +800,10 @@ and record its identity in the selector table. --*/ bc = 999999999; bt = -1; - for (int t = 0; t < nGroups; ++t) { - if (cost[t] < bc) { + for (int t = 0; t < nGroups; ++t) + { + if (cost[t] < bc) + { bc = cost[t]; bt = t; } @@ -731,7 +816,8 @@ and record its identity in the selector table. /*-- Increment the symbol frequencies for the selected table. --*/ - for (int i = gs; i <= ge; ++i) { + for (int i = gs; i <= ge; ++i) + { ++rfreq[bt][szptr[i]]; } @@ -741,7 +827,8 @@ and record its identity in the selector table. /*-- Recompute the tables based on the accumulated frequencies. --*/ - for (int t = 0; t < nGroups; ++t) { + for (int t = 0; t < nGroups; ++t) + { HbMakeCodeLengths(len[t], rfreq[t], alphaSize, 20); } } @@ -750,11 +837,13 @@ Recompute the tables based on the accumulated frequencies. fave = null; cost = null; - if (!(nGroups < 8)) { + if (!(nGroups < 8)) + { Panic(); } - if (!(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZip2Constants.GroupSize)))) { + if (!(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZip2Constants.GroupSize)))) + { Panic(); } @@ -762,15 +851,18 @@ Recompute the tables based on the accumulated frequencies. char[] pos = new char[BZip2Constants.GroupCount]; char ll_i, tmp2, tmp; - for (int i = 0; i < nGroups; i++) { + for (int i = 0; i < nGroups; i++) + { pos[i] = (char)i; } - for (int i = 0; i < nSelectors; i++) { + for (int i = 0; i < nSelectors; i++) + { ll_i = selector[i]; int j = 0; tmp = pos[j]; - while (ll_i != tmp) { + while (ll_i != tmp) + { j++; tmp2 = tmp; tmp = pos[j]; @@ -782,26 +874,33 @@ Recompute the tables based on the accumulated frequencies. int[][] code = new int[BZip2Constants.GroupCount][]; - for (int i = 0; i < BZip2Constants.GroupCount; ++i) { + for (int i = 0; i < BZip2Constants.GroupCount; ++i) + { code[i] = new int[BZip2Constants.MaximumAlphaSize]; } /*--- Assign actual codes for the tables. --*/ - for (int t = 0; t < nGroups; t++) { + for (int t = 0; t < nGroups; t++) + { minLen = 32; maxLen = 0; - for (int i = 0; i < alphaSize; i++) { - if (len[t][i] > maxLen) { + for (int i = 0; i < alphaSize; i++) + { + if (len[t][i] > maxLen) + { maxLen = len[t][i]; } - if (len[t][i] < minLen) { + if (len[t][i] < minLen) + { minLen = len[t][i]; } } - if (maxLen > 20) { + if (maxLen > 20) + { Panic(); } - if (minLen < 1) { + if (minLen < 1) + { Panic(); } HbAssignCodes(code[t], len[t], minLen, maxLen, alphaSize); @@ -809,29 +908,42 @@ Recompute the tables based on the accumulated frequencies. /*--- Transmit the mapping table. ---*/ bool[] inUse16 = new bool[16]; - for (int i = 0; i < 16; ++i) { + for (int i = 0; i < 16; ++i) + { inUse16[i] = false; - for (int j = 0; j < 16; ++j) { - if (inUse[i * 16 + j]) { + for (int j = 0; j < 16; ++j) + { + if (inUse[i * 16 + j]) + { inUse16[i] = true; } } } - for (int i = 0; i < 16; ++i) { - if (inUse16[i]) { + for (int i = 0; i < 16; ++i) + { + if (inUse16[i]) + { BsW(1, 1); - } else { + } + else + { BsW(1, 0); } } - for (int i = 0; i < 16; ++i) { - if (inUse16[i]) { - for (int j = 0; j < 16; ++j) { - if (inUse[i * 16 + j]) { + for (int i = 0; i < 16; ++i) + { + if (inUse16[i]) + { + for (int j = 0; j < 16; ++j) + { + if (inUse[i * 16 + j]) + { BsW(1, 1); - } else { + } + else + { BsW(1, 0); } } @@ -841,23 +953,29 @@ Recompute the tables based on the accumulated frequencies. /*--- Now the selectors. ---*/ BsW(3, nGroups); BsW(15, nSelectors); - for (int i = 0; i < nSelectors; ++i) { - for (int j = 0; j < selectorMtf[i]; ++j) { + for (int i = 0; i < nSelectors; ++i) + { + for (int j = 0; j < selectorMtf[i]; ++j) + { BsW(1, 1); } BsW(1, 0); } /*--- Now the coding tables. ---*/ - for (int t = 0; t < nGroups; ++t) { + for (int t = 0; t < nGroups; ++t) + { int curr = len[t][0]; BsW(5, curr); - for (int i = 0; i < alphaSize; ++i) { - while (curr < len[t][i]) { + for (int i = 0; i < alphaSize; ++i) + { + while (curr < len[t][i]) + { BsW(2, 2); curr++; /* 10 */ } - while (curr > len[t][i]) { + while (curr > len[t][i]) + { BsW(2, 3); curr--; /* 11 */ } @@ -868,61 +986,71 @@ Recompute the tables based on the accumulated frequencies. /*--- And finally, the block data proper ---*/ selCtr = 0; gs = 0; - while (true) { - if (gs >= nMTF) { + while (true) + { + if (gs >= nMTF) + { break; } ge = gs + BZip2Constants.GroupSize - 1; - if (ge >= nMTF) { + if (ge >= nMTF) + { ge = nMTF - 1; } - for (int i = gs; i <= ge; i++) { + for (int i = gs; i <= ge; i++) + { BsW(len[selector[selCtr]][szptr[i]], code[selector[selCtr]][szptr[i]]); } gs = ge + 1; ++selCtr; } - if (!(selCtr == nSelectors)) { + if (!(selCtr == nSelectors)) + { Panic(); } } - void MoveToFrontCodeAndSend() + private void MoveToFrontCodeAndSend() { BsPutIntVS(24, origPtr); GenerateMTFValues(); SendMTFValues(); } - void SimpleSort(int lo, int hi, int d) + private void SimpleSort(int lo, int hi, int d) { int i, j, h, bigN, hp; int v; bigN = hi - lo + 1; - if (bigN < 2) { + if (bigN < 2) + { return; } hp = 0; - while (increments[hp] < bigN) { + while (increments[hp] < bigN) + { hp++; } hp--; - for (; hp >= 0; hp--) { + for (; hp >= 0; hp--) + { h = increments[hp]; i = lo + h; - while (true) { + while (true) + { /*-- copy 1 --*/ if (i > hi) break; v = zptr[i]; j = i; - while (FullGtU(zptr[j - h] + d, v + d)) { + while (FullGtU(zptr[j - h] + d, v + d)) + { zptr[j] = zptr[j - h]; j = j - h; if (j <= (lo + h - 1)) @@ -932,15 +1060,18 @@ void SimpleSort(int lo, int hi, int d) i++; /*-- copy 2 --*/ - if (i > hi) { + if (i > hi) + { break; } v = zptr[i]; j = i; - while (FullGtU(zptr[j - h] + d, v + d)) { + while (FullGtU(zptr[j - h] + d, v + d)) + { zptr[j] = zptr[j - h]; j = j - h; - if (j <= (lo + h - 1)) { + if (j <= (lo + h - 1)) + { break; } } @@ -948,32 +1079,37 @@ void SimpleSort(int lo, int hi, int d) i++; /*-- copy 3 --*/ - if (i > hi) { + if (i > hi) + { break; } v = zptr[i]; j = i; - while (FullGtU(zptr[j - h] + d, v + d)) { + while (FullGtU(zptr[j - h] + d, v + d)) + { zptr[j] = zptr[j - h]; j = j - h; - if (j <= (lo + h - 1)) { + if (j <= (lo + h - 1)) + { break; } } zptr[j] = v; i++; - if (workDone > workLimit && firstAttempt) { + if (workDone > workLimit && firstAttempt) + { return; } } } } - void Vswap(int p1, int p2, int n) + private void Vswap(int p1, int p2, int n) { int temp = 0; - while (n > 0) { + while (n > 0) + { temp = zptr[p1]; zptr[p1] = zptr[p2]; zptr[p2] = temp; @@ -983,7 +1119,7 @@ void Vswap(int p1, int p2, int n) } } - void QSort3(int loSt, int hiSt, int dSt) + private void QSort3(int loSt, int hiSt, int dSt) { int unLo, unHi, ltLo, gtHi, med, n, m; int lo, hi, d; @@ -997,8 +1133,10 @@ void QSort3(int loSt, int hiSt, int dSt) stack[sp].dd = dSt; sp++; - while (sp > 0) { - if (sp >= QSORT_STACK_SIZE) { + while (sp > 0) + { + if (sp >= QSORT_STACK_SIZE) + { Panic(); } @@ -1007,9 +1145,11 @@ void QSort3(int loSt, int hiSt, int dSt) hi = stack[sp].hh; d = stack[sp].dd; - if (hi - lo < SMALL_THRESH || d > DEPTH_THRESH) { + if (hi - lo < SMALL_THRESH || d > DEPTH_THRESH) + { SimpleSort(lo, hi, d); - if (workDone > workLimit && firstAttempt) { + if (workDone > workLimit && firstAttempt) + { return; } continue; @@ -1022,13 +1162,17 @@ void QSort3(int loSt, int hiSt, int dSt) unLo = ltLo = lo; unHi = gtHi = hi; - while (true) { - while (true) { - if (unLo > unHi) { + while (true) + { + while (true) + { + if (unLo > unHi) + { break; } n = ((int)block[zptr[unLo] + d + 1]) - med; - if (n == 0) { + if (n == 0) + { int temp = zptr[unLo]; zptr[unLo] = zptr[ltLo]; zptr[ltLo] = temp; @@ -1036,18 +1180,22 @@ void QSort3(int loSt, int hiSt, int dSt) unLo++; continue; } - if (n > 0) { + if (n > 0) + { break; } unLo++; } - while (true) { - if (unLo > unHi) { + while (true) + { + if (unLo > unHi) + { break; } n = ((int)block[zptr[unHi] + d + 1]) - med; - if (n == 0) { + if (n == 0) + { int temp = zptr[unHi]; zptr[unHi] = zptr[gtHi]; zptr[gtHi] = temp; @@ -1055,13 +1203,15 @@ void QSort3(int loSt, int hiSt, int dSt) unHi--; continue; } - if (n < 0) { + if (n < 0) + { break; } unHi--; } - if (unLo > unHi) { + if (unLo > unHi) + { break; } @@ -1074,7 +1224,8 @@ void QSort3(int loSt, int hiSt, int dSt) } } - if (gtHi < ltLo) { + if (gtHi < ltLo) + { stack[sp].ll = lo; stack[sp].hh = hi; stack[sp].dd = d + 1; @@ -1107,7 +1258,7 @@ void QSort3(int loSt, int hiSt, int dSt) } } - void MainSort() + private void MainSort() { int i, j, ss, sb; int[] runningOrder = new int[256]; @@ -1123,48 +1274,59 @@ void MainSort() --*/ // if (verbosity >= 4) fprintf ( stderr, " sort initialise ...\n" ); - for (i = 0; i < BZip2Constants.OvershootBytes; i++) { + for (i = 0; i < BZip2Constants.OvershootBytes; i++) + { block[last + i + 2] = block[(i % (last + 1)) + 1]; } - for (i = 0; i <= last + BZip2Constants.OvershootBytes; i++) { + for (i = 0; i <= last + BZip2Constants.OvershootBytes; i++) + { quadrant[i] = 0; } block[0] = (byte)(block[last + 1]); - if (last < 4000) { + if (last < 4000) + { /*-- Use simpleSort(), since the full sorting mechanism has quite a large constant overhead. --*/ - for (i = 0; i <= last; i++) { + for (i = 0; i <= last; i++) + { zptr[i] = i; } firstAttempt = false; workDone = workLimit = 0; SimpleSort(0, last, 0); - } else { + } + else + { numQSorted = 0; - for (i = 0; i <= 255; i++) { + for (i = 0; i <= 255; i++) + { bigDone[i] = false; } - for (i = 0; i <= 65536; i++) { + for (i = 0; i <= 65536; i++) + { ftab[i] = 0; } c1 = block[0]; - for (i = 0; i <= last; i++) { + for (i = 0; i <= last; i++) + { c2 = block[i + 1]; ftab[(c1 << 8) + c2]++; c1 = c2; } - for (i = 1; i <= 65536; i++) { + for (i = 1; i <= 65536; i++) + { ftab[i] += ftab[i - 1]; } c1 = block[1]; - for (i = 0; i < last; i++) { + for (i = 0; i < last; i++) + { c2 = block[i + 2]; j = (c1 << 8) + c2; c1 = c2; @@ -1182,24 +1344,30 @@ Now ftab contains the first loc of every small bucket. big bucket. --*/ - for (i = 0; i <= 255; i++) { + for (i = 0; i <= 255; i++) + { runningOrder[i] = i; } int vv; int h = 1; - do { + do + { h = 3 * h + 1; } while (h <= 256); - do { + do + { h = h / 3; - for (i = h; i <= 255; i++) { + for (i = h; i <= 255; i++) + { vv = runningOrder[i]; j = i; - while ((ftab[((runningOrder[j - h]) + 1) << 8] - ftab[(runningOrder[j - h]) << 8]) > (ftab[((vv) + 1) << 8] - ftab[(vv) << 8])) { + while ((ftab[((runningOrder[j - h]) + 1) << 8] - ftab[(runningOrder[j - h]) << 8]) > (ftab[((vv) + 1) << 8] - ftab[(vv) << 8])) + { runningOrder[j] = runningOrder[j - h]; j = j - h; - if (j <= (h - 1)) { + if (j <= (h - 1)) + { break; } } @@ -1210,8 +1378,8 @@ big bucket. /*-- The main sorting loop. --*/ - for (i = 0; i <= 255; i++) { - + for (i = 0; i <= 255; i++) + { /*-- Process big buckets, starting with the least full. --*/ @@ -1224,15 +1392,19 @@ previous pointer-scanning phases have already completed many of the small buckets [ss, j], so we don't have to sort them at all. --*/ - for (j = 0; j <= 255; j++) { + for (j = 0; j <= 255; j++) + { sb = (ss << 8) + j; - if (!((ftab[sb] & SETMASK) == SETMASK)) { + if (!((ftab[sb] & SETMASK) == SETMASK)) + { int lo = ftab[sb] & CLEARMASK; int hi = (ftab[sb + 1] & CLEARMASK) - 1; - if (hi > lo) { + if (hi > lo) + { QSort3(lo, hi, 2); numQSorted += (hi - lo + 1); - if (workDone > workLimit && firstAttempt) { + if (workDone > workLimit && firstAttempt) + { return; } } @@ -1250,25 +1422,30 @@ and update the quadrant descriptors. Remember to --*/ bigDone[ss] = true; - if (i < 255) { + if (i < 255) + { int bbStart = ftab[ss << 8] & CLEARMASK; int bbSize = (ftab[(ss + 1) << 8] & CLEARMASK) - bbStart; int shifts = 0; - while ((bbSize >> shifts) > 65534) { + while ((bbSize >> shifts) > 65534) + { shifts++; } - for (j = 0; j < bbSize; j++) { + for (j = 0; j < bbSize; j++) + { int a2update = zptr[bbStart + j]; int qVal = (j >> shifts); quadrant[a2update] = qVal; - if (a2update < BZip2Constants.OvershootBytes) { + if (a2update < BZip2Constants.OvershootBytes) + { quadrant[a2update + last + 1] = qVal; } } - if (!(((bbSize - 1) >> shifts) <= 65535)) { + if (!(((bbSize - 1) >> shifts) <= 65535)) + { Panic(); } } @@ -1277,39 +1454,47 @@ and update the quadrant descriptors. Remember to Now scan this big bucket so as to synthesise the sorted order for small buckets [t, ss] for all t != ss. --*/ - for (j = 0; j <= 255; j++) { + for (j = 0; j <= 255; j++) + { copy[j] = ftab[(j << 8) + ss] & CLEARMASK; } - for (j = ftab[ss << 8] & CLEARMASK; j < (ftab[(ss + 1) << 8] & CLEARMASK); j++) { + for (j = ftab[ss << 8] & CLEARMASK; j < (ftab[(ss + 1) << 8] & CLEARMASK); j++) + { c1 = block[zptr[j]]; - if (!bigDone[c1]) { + if (!bigDone[c1]) + { zptr[copy[c1]] = zptr[j] == 0 ? last : zptr[j] - 1; copy[c1]++; } } - for (j = 0; j <= 255; j++) { + for (j = 0; j <= 255; j++) + { ftab[(j << 8) + ss] |= SETMASK; } } } } - void RandomiseBlock() + private void RandomiseBlock() { int i; int rNToGo = 0; int rTPos = 0; - for (i = 0; i < 256; i++) { + for (i = 0; i < 256; i++) + { inUse[i] = false; } - for (i = 0; i <= last; i++) { - if (rNToGo == 0) { + for (i = 0; i <= last; i++) + { + if (rNToGo == 0) + { rNToGo = (int)BZip2Constants.RandomNumbers[rTPos]; rTPos++; - if (rTPos == 512) { + if (rTPos == 512) + { rTPos = 0; } } @@ -1322,7 +1507,7 @@ void RandomiseBlock() } } - void DoReversibleTransformation() + private void DoReversibleTransformation() { workLimit = workFactor * last; workDone = 0; @@ -1331,7 +1516,8 @@ void DoReversibleTransformation() MainSort(); - if (workDone > workLimit && firstAttempt) { + if (workDone > workLimit && firstAttempt) + { RandomiseBlock(); workLimit = workDone = 0; blockRandomised = true; @@ -1340,19 +1526,22 @@ void DoReversibleTransformation() } origPtr = -1; - for (int i = 0; i <= last; i++) { - if (zptr[i] == 0) { + for (int i = 0; i <= last; i++) + { + if (zptr[i] == 0) + { origPtr = i; break; } } - if (origPtr == -1) { + if (origPtr == -1) + { Panic(); } } - bool FullGtU(int i1, int i2) + private bool FullGtU(int i1, int i2) { int k; byte c1, c2; @@ -1360,7 +1549,8 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } i1++; @@ -1368,7 +1558,8 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } i1++; @@ -1376,7 +1567,8 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } i1++; @@ -1384,7 +1576,8 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } i1++; @@ -1392,7 +1585,8 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } i1++; @@ -1400,7 +1594,8 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } i1++; @@ -1408,15 +1603,18 @@ bool FullGtU(int i1, int i2) k = last + 1; - do { + do + { c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) { + if (s1 != s2) + { return s1 > s2; } i1++; @@ -1424,12 +1622,14 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) { + if (s1 != s2) + { return s1 > s2; } i1++; @@ -1437,12 +1637,14 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) { + if (s1 != s2) + { return s1 > s2; } i1++; @@ -1450,22 +1652,26 @@ bool FullGtU(int i1, int i2) c1 = block[i1 + 1]; c2 = block[i2 + 1]; - if (c1 != c2) { + if (c1 != c2) + { return c1 > c2; } s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) { + if (s1 != s2) + { return s1 > s2; } i1++; i2++; - if (i1 > last) { + if (i1 > last) + { i1 -= last; i1--; } - if (i2 > last) { + if (i2 > last) + { i2 -= last; i2--; } @@ -1477,7 +1683,7 @@ bool FullGtU(int i1, int i2) return false; } - void AllocateCompressStructures() + private void AllocateCompressStructures() { int n = BZip2Constants.BaseBlockSize * blockSize100k; block = new byte[(n + 1 + BZip2Constants.OvershootBytes)]; @@ -1485,7 +1691,8 @@ void AllocateCompressStructures() zptr = new int[n]; ftab = new int[65537]; - if (block == null || quadrant == null || zptr == null || ftab == null) { + if (block == null || quadrant == null || zptr == null || ftab == null) + { // int totalDraw = (n + 1 + NUM_OVERSHOOT_BYTES) + (n + NUM_OVERSHOOT_BYTES) + n + 65537; // compressOutOfMemory ( totalDraw, n ); } @@ -1502,11 +1709,10 @@ Seems to improve compression speed by about 1%. */ // szptr = zptr; - szptr = new short[2 * n]; } - void GenerateMTFValues() + private void GenerateMTFValues() { char[] yy = new char[256]; int i, j; @@ -1519,25 +1725,28 @@ void GenerateMTFValues() MakeMaps(); EOB = nInUse + 1; - for (i = 0; i <= EOB; i++) { + for (i = 0; i <= EOB; i++) + { mtfFreq[i] = 0; } wr = 0; zPend = 0; - for (i = 0; i < nInUse; i++) { + for (i = 0; i < nInUse; i++) + { yy[i] = (char)i; } - - for (i = 0; i <= last; i++) { + for (i = 0; i <= last; i++) + { char ll_i; ll_i = unseqToSeq[block[zptr[i]]]; j = 0; tmp = yy[j]; - while (ll_i != tmp) { + while (ll_i != tmp) + { j++; tmp2 = tmp; tmp = yy[j]; @@ -1545,25 +1754,33 @@ void GenerateMTFValues() } yy[0] = tmp; - if (j == 0) { + if (j == 0) + { zPend++; - } else { - if (zPend > 0) { + } + else + { + if (zPend > 0) + { zPend--; - while (true) { - switch (zPend % 2) { - case 0: - szptr[wr] = (short)BZip2Constants.RunA; - wr++; - mtfFreq[BZip2Constants.RunA]++; - break; - case 1: - szptr[wr] = (short)BZip2Constants.RunB; - wr++; - mtfFreq[BZip2Constants.RunB]++; - break; + while (true) + { + switch (zPend % 2) + { + case 0: + szptr[wr] = (short)BZip2Constants.RunA; + wr++; + mtfFreq[BZip2Constants.RunA]++; + break; + + case 1: + szptr[wr] = (short)BZip2Constants.RunB; + wr++; + mtfFreq[BZip2Constants.RunB]++; + break; } - if (zPend < 2) { + if (zPend < 2) + { break; } zPend = (zPend - 2) / 2; @@ -1576,22 +1793,27 @@ void GenerateMTFValues() } } - if (zPend > 0) { + if (zPend > 0) + { zPend--; - while (true) { - switch (zPend % 2) { - case 0: - szptr[wr] = (short)BZip2Constants.RunA; - wr++; - mtfFreq[BZip2Constants.RunA]++; - break; - case 1: - szptr[wr] = (short)BZip2Constants.RunB; - wr++; - mtfFreq[BZip2Constants.RunB]++; - break; + while (true) + { + switch (zPend % 2) + { + case 0: + szptr[wr] = (short)BZip2Constants.RunA; + wr++; + mtfFreq[BZip2Constants.RunA]++; + break; + + case 1: + szptr[wr] = (short)BZip2Constants.RunB; + wr++; + mtfFreq[BZip2Constants.RunB]++; + break; } - if (zPend < 2) { + if (zPend < 2) + { break; } zPend = (zPend - 2) / 2; @@ -1605,12 +1827,12 @@ void GenerateMTFValues() nMTF = wr; } - static void Panic() + private static void Panic() { throw new BZip2Exception("BZip2 output stream panic"); } - static void HbMakeCodeLengths(char[] len, int[] freq, int alphaSize, int maxLen) + private static void HbMakeCodeLengths(char[] len, int[] freq, int alphaSize, int maxLen) { /*-- Nodes and heap entries run from 1. Entry 0 @@ -1623,11 +1845,13 @@ Nodes and heap entries run from 1. Entry 0 int[] weight = new int[BZip2Constants.MaximumAlphaSize * 2]; int[] parent = new int[BZip2Constants.MaximumAlphaSize * 2]; - for (int i = 0; i < alphaSize; ++i) { + for (int i = 0; i < alphaSize; ++i) + { weight[i + 1] = (freq[i] == 0 ? 1 : freq[i]) << 8; } - while (true) { + while (true) + { nNodes = alphaSize; nHeap = 0; @@ -1635,38 +1859,46 @@ Nodes and heap entries run from 1. Entry 0 weight[0] = 0; parent[0] = -2; - for (int i = 1; i <= alphaSize; ++i) { + for (int i = 1; i <= alphaSize; ++i) + { parent[i] = -1; nHeap++; heap[nHeap] = i; int zz = nHeap; int tmp = heap[zz]; - while (weight[tmp] < weight[heap[zz >> 1]]) { + while (weight[tmp] < weight[heap[zz >> 1]]) + { heap[zz] = heap[zz >> 1]; zz >>= 1; } heap[zz] = tmp; } - if (!(nHeap < (BZip2Constants.MaximumAlphaSize + 2))) { + if (!(nHeap < (BZip2Constants.MaximumAlphaSize + 2))) + { Panic(); } - while (nHeap > 1) { + while (nHeap > 1) + { n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; int zz = 1; int yy = 0; int tmp = heap[zz]; - while (true) { + while (true) + { yy = zz << 1; - if (yy > nHeap) { + if (yy > nHeap) + { break; } - if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]]) { + if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]]) + { yy++; } - if (weight[tmp] < weight[heap[yy]]) { + if (weight[tmp] < weight[heap[yy]]) + { break; } @@ -1681,15 +1913,19 @@ Nodes and heap entries run from 1. Entry 0 zz = 1; yy = 0; tmp = heap[zz]; - while (true) { + while (true) + { yy = zz << 1; - if (yy > nHeap) { + if (yy > nHeap) + { break; } - if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]]) { + if (yy < nHeap && weight[heap[yy + 1]] < weight[heap[yy]]) + { yy++; } - if (weight[tmp] < weight[heap[yy]]) { + if (weight[tmp] < weight[heap[yy]]) + { break; } heap[zz] = heap[yy]; @@ -1708,21 +1944,25 @@ Nodes and heap entries run from 1. Entry 0 zz = nHeap; tmp = heap[zz]; - while (weight[tmp] < weight[heap[zz >> 1]]) { + while (weight[tmp] < weight[heap[zz >> 1]]) + { heap[zz] = heap[zz >> 1]; zz >>= 1; } heap[zz] = tmp; } - if (!(nNodes < (BZip2Constants.MaximumAlphaSize * 2))) { + if (!(nNodes < (BZip2Constants.MaximumAlphaSize * 2))) + { Panic(); } tooLong = false; - for (int i = 1; i <= alphaSize; ++i) { + for (int i = 1; i <= alphaSize; ++i) + { j = 0; k = i; - while (parent[k] >= 0) { + while (parent[k] >= 0) + { k = parent[k]; j++; } @@ -1730,11 +1970,13 @@ Nodes and heap entries run from 1. Entry 0 tooLong |= j > maxLen; } - if (!tooLong) { + if (!tooLong) + { break; } - for (int i = 1; i < alphaSize; ++i) { + for (int i = 1; i < alphaSize; ++i) + { j = weight[i] >> 8; j = 1 + (j / 2); weight[i] = j << 8; @@ -1742,12 +1984,15 @@ Nodes and heap entries run from 1. Entry 0 } } - static void HbAssignCodes(int[] code, char[] length, int minLen, int maxLen, int alphaSize) + private static void HbAssignCodes(int[] code, char[] length, int minLen, int maxLen, int alphaSize) { int vec = 0; - for (int n = minLen; n <= maxLen; ++n) { - for (int i = 0; i < alphaSize; ++i) { - if (length[i] == n) { + for (int n = minLen; n <= maxLen; ++n) + { + for (int i = 0; i < alphaSize; ++i) + { + if (length[i] == n) + { code[i] = vec; ++vec; } @@ -1756,26 +2001,29 @@ static void HbAssignCodes(int[] code, char[] length, int minLen, int maxLen, int } } - static byte Med3(byte a, byte b, byte c) + private static byte Med3(byte a, byte b, byte c) { byte t; - if (a > b) { + if (a > b) + { t = a; a = b; b = t; } - if (b > c) { + if (b > c) + { t = b; b = c; c = t; } - if (a > b) { + if (a > b) + { b = a; } return b; } - struct StackElement + private struct StackElement { public int ll; public int hh; diff --git a/src/ICSharpCode.SharpZipLib/Checksum/Adler32.cs b/src/ICSharpCode.SharpZipLib/Checksum/Adler32.cs index 0b9f345c8..2684b642c 100644 --- a/src/ICSharpCode.SharpZipLib/Checksum/Adler32.cs +++ b/src/ICSharpCode.SharpZipLib/Checksum/Adler32.cs @@ -6,31 +6,31 @@ namespace ICSharpCode.SharpZipLib.Checksum /// Computes Adler32 checksum for a stream of data. An Adler32 /// checksum is not as reliable as a CRC32 checksum, but a lot faster to /// compute. - /// + /// /// The specification for Adler32 may be found in RFC 1950. /// ZLIB Compressed Data Format Specification version 3.3) - /// - /// + /// + /// /// From that document: - /// + /// /// "ADLER32 (Adler-32 checksum) /// This contains a checksum value of the uncompressed data /// (excluding any dictionary data) computed according to Adler-32 /// algorithm. This algorithm is a 32-bit extension and improvement /// of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 /// standard. - /// + /// /// Adler-32 is composed of two sums accumulated per byte: s1 is /// the sum of all bytes, s2 is the sum of all s1 values. Both sums /// are done modulo 65521. s1 is initialized to 1, s2 to zero. The /// Adler-32 checksum is stored as s2*65536 + s1 in most- /// significant-byte first (network) order." - /// + /// /// "8.2. The Adler-32 algorithm - /// + /// /// The Adler-32 algorithm is much faster than the CRC32 algorithm yet /// still provides an extremely low probability of undetected errors. - /// + /// /// The modulo on unsigned long accumulators can be delayed for 5552 /// bytes, so the modulo operation time is negligible. If the bytes /// are a, b, c, the second sum is 3a + 2b + c + 3, and so is position @@ -40,7 +40,7 @@ namespace ICSharpCode.SharpZipLib.Checksum /// (The Fletcher checksum uses 255, which is not prime and which also /// makes the Fletcher check insensitive to single byte changes 0 - /// 255.) - /// + /// /// The sum s1 is initialized to 1 instead of zero to make the length /// of the sequence part of s2, so that the length does not have to be /// checked separately. (Any sequence of zeroes has a Fletcher @@ -51,20 +51,22 @@ namespace ICSharpCode.SharpZipLib.Checksum public sealed class Adler32 : IChecksum { #region Instance Fields + /// /// largest prime smaller than 65536 /// - readonly static uint BASE = 65521; + private static readonly uint BASE = 65521; /// /// The CRC data checksum so far. /// - uint checkValue; - #endregion + private uint checkValue; + + #endregion Instance Fields /// /// Initialise a default instance of - /// + /// public Adler32() { Reset(); @@ -81,8 +83,10 @@ public void Reset() /// /// Returns the Adler32 data checksum computed so far. /// - public long Value { - get { + public long Value + { + get + { return checkValue; } } @@ -107,13 +111,14 @@ public void Update(int bval) } /// - /// Updates the Adler32 data checksum with the bytes taken from + /// Updates the Adler32 data checksum with the bytes taken from /// a block of data. /// /// Contains the data to update the checksum with. public void Update(byte[] buffer) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } diff --git a/src/ICSharpCode.SharpZipLib/Checksum/BZip2Crc.cs b/src/ICSharpCode.SharpZipLib/Checksum/BZip2Crc.cs index b4fd80ef8..aac3075b6 100644 --- a/src/ICSharpCode.SharpZipLib/Checksum/BZip2Crc.cs +++ b/src/ICSharpCode.SharpZipLib/Checksum/BZip2Crc.cs @@ -32,10 +32,11 @@ namespace ICSharpCode.SharpZipLib.Checksum public sealed class BZip2Crc : IChecksum { #region Instance Fields - const uint crcInit = 0xFFFFFFFF; + + private const uint crcInit = 0xFFFFFFFF; //const uint crcXor = 0x00000000; - readonly static uint[] crcTable = { + private static readonly uint[] crcTable = { 0X00000000, 0X04C11DB7, 0X09823B6E, 0X0D4326D9, 0X130476DC, 0X17C56B6B, 0X1A864DB2, 0X1E475005, 0X2608EDB8, 0X22C9F00F, 0X2F8AD6D6, 0X2B4BCB61, @@ -105,12 +106,13 @@ public sealed class BZip2Crc : IChecksum /// /// The CRC data checksum so far. /// - uint checkValue; - #endregion + private uint checkValue; + + #endregion Instance Fields /// /// Initialise a default instance of - /// + /// public BZip2Crc() { Reset(); @@ -128,8 +130,10 @@ public void Reset() /// Returns the CRC data checksum computed so far. /// /// Reversed Out = true - public long Value { - get { + public long Value + { + get + { // Tehcnically, the output should be: //return (long)(~checkValue ^ crcXor); // but x ^ 0 = x, so there is no point in adding @@ -151,13 +155,14 @@ public void Update(int bval) } /// - /// Updates the CRC data checksum with the bytes taken from + /// Updates the CRC data checksum with the bytes taken from /// a block of data. /// /// Contains the data to update the CRC with. public void Update(byte[] buffer) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } diff --git a/src/ICSharpCode.SharpZipLib/Checksum/Crc32.cs b/src/ICSharpCode.SharpZipLib/Checksum/Crc32.cs index 2784bbb25..f9861685a 100644 --- a/src/ICSharpCode.SharpZipLib/Checksum/Crc32.cs +++ b/src/ICSharpCode.SharpZipLib/Checksum/Crc32.cs @@ -32,10 +32,11 @@ namespace ICSharpCode.SharpZipLib.Checksum public sealed class Crc32 : IChecksum { #region Instance Fields - readonly static uint crcInit = 0xFFFFFFFF; - readonly static uint crcXor = 0xFFFFFFFF; - readonly static uint[] crcTable = { + private static readonly uint crcInit = 0xFFFFFFFF; + private static readonly uint crcXor = 0xFFFFFFFF; + + private static readonly uint[] crcTable = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, @@ -93,8 +94,9 @@ public sealed class Crc32 : IChecksum /// /// The CRC data checksum so far. /// - uint checkValue; - #endregion + private uint checkValue; + + #endregion Instance Fields internal static uint ComputeCrc32(uint oldCrc, byte bval) { @@ -121,8 +123,10 @@ public void Reset() /// Returns the CRC data checksum computed so far. /// /// Reversed Out = false - public long Value { - get { + public long Value + { + get + { return (long)(checkValue ^ crcXor); } } @@ -140,13 +144,14 @@ public void Update(int bval) } /// - /// Updates the CRC data checksum with the bytes taken from + /// Updates the CRC data checksum with the bytes taken from /// a block of data. /// /// Contains the data to update the CRC with. public void Update(byte[] buffer) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } @@ -161,7 +166,8 @@ public void Update(byte[] buffer) /// public void Update(ArraySegment segment) { - foreach (byte b in segment) { + foreach (byte b in segment) + { Update(b); } } diff --git a/src/ICSharpCode.SharpZipLib/Checksum/IChecksum.cs b/src/ICSharpCode.SharpZipLib/Checksum/IChecksum.cs index 45c073a91..db74a5a5d 100644 --- a/src/ICSharpCode.SharpZipLib/Checksum/IChecksum.cs +++ b/src/ICSharpCode.SharpZipLib/Checksum/IChecksum.cs @@ -19,7 +19,8 @@ public interface IChecksum /// /// Returns the data checksum computed so far. /// - long Value { + long Value + { get; } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs index 45686effe..8ce046d9e 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs @@ -2,12 +2,12 @@ namespace ICSharpCode.SharpZipLib { - /// - /// SharpZipBaseException is the base exception class for SharpZipLib. - /// All library exceptions are derived from this. - /// - /// NOTE: Not all exceptions thrown will be derived from this class. - /// A variety of other exceptions are possible for example + /// + /// SharpZipBaseException is the base exception class for SharpZipLib. + /// All library exceptions are derived from this. + /// + /// NOTE: Not all exceptions thrown will be derived from this class. + /// A variety of other exceptions are possible for example public class SharpZipBaseException : Exception { /// diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs index 4882a9f4d..df247a6bd 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs @@ -1,15 +1,13 @@ using System; -using System.Collections.Generic; -using System.Text; namespace ICSharpCode.SharpZipLib { - /// - /// Indicates that an error occured during decoding of a input stream due to corrupt + /// + /// Indicates that an error occured during decoding of a input stream due to corrupt /// data or (unintentional) library incompability. - /// - public class StreamDecodingException: SharpZipBaseException - { + /// + public class StreamDecodingException : SharpZipBaseException + { private const string GenericMessage = "Input stream could not be decoded"; /// @@ -23,7 +21,6 @@ public StreamDecodingException() : base(GenericMessage) { } /// A message describing the exception. public StreamDecodingException(string message) : base(message) { } - /// /// Initializes a new instance of the StreamDecodingException class with a specified /// error message and a reference to the inner exception that is the cause of this exception. diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs index ff8579c4d..7fdc7a4ce 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs @@ -20,7 +20,6 @@ public StreamUnsupportedException() : base(GenericMessage) { } /// A message describing the exception. public StreamUnsupportedException(string message) : base(message) { } - /// /// Initializes a new instance of the StreamUnsupportedException class with a specified /// error message and a reference to the inner exception that is the cause of this exception. @@ -28,6 +27,5 @@ public StreamUnsupportedException(string message) : base(message) { } /// A message describing the exception. /// The inner exception public StreamUnsupportedException(string message, Exception innerException) : base(message, innerException) { } - } } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs index 975d6f796..fc8391851 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs @@ -20,7 +20,6 @@ public UnexpectedEndOfStreamException() : base(GenericMessage) { } /// A message describing the exception. public UnexpectedEndOfStreamException(string message) : base(message) { } - /// /// Initializes a new instance of the UnexpectedEndOfStreamException class with a specified /// error message and a reference to the inner exception that is the cause of this exception. @@ -28,6 +27,5 @@ public UnexpectedEndOfStreamException(string message) : base(message) { } /// A message describing the exception. /// The inner exception public UnexpectedEndOfStreamException(string message, Exception innerException) : base(message, innerException) { } - } } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs index 47a3aaea5..2af5d6e12 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs @@ -1,10 +1,7 @@ using System; -using System.Collections.Generic; -using System.Text; namespace ICSharpCode.SharpZipLib { - /// /// Indicates that a value was outside of the expected range when decoding an input stream /// @@ -14,7 +11,7 @@ public class ValueOutOfRangeException : StreamDecodingException /// Initializes a new instance of the ValueOutOfRangeException class naming the the causing variable /// /// Name of the variable, use: nameof() - public ValueOutOfRangeException(string nameOfValue ) + public ValueOutOfRangeException(string nameOfValue) : base($"{nameOfValue} out of range") { } /// @@ -25,7 +22,7 @@ public ValueOutOfRangeException(string nameOfValue ) /// The invalid value /// Expected maximum value /// Expected minimum value - public ValueOutOfRangeException(string nameOfValue, long value, long maxValue, long minValue = 0) + public ValueOutOfRangeException(string nameOfValue, long value, long maxValue, long minValue = 0) : this(nameOfValue, value.ToString(), maxValue.ToString(), minValue.ToString()) { } /// @@ -37,9 +34,15 @@ public ValueOutOfRangeException(string nameOfValue, long value, long maxValue, l /// Expected maximum value /// Expected minimum value public ValueOutOfRangeException(string nameOfValue, string value, string maxValue, string minValue = "0") : - base($"{nameOfValue} out of range: {value}, should be {minValue}..{maxValue}") { } + base($"{nameOfValue} out of range: {value}, should be {minValue}..{maxValue}") + { } + + private ValueOutOfRangeException() + { + } - private ValueOutOfRangeException() { } - private ValueOutOfRangeException(string message, Exception innerException) : base(message, innerException) {} + private ValueOutOfRangeException(string message, Exception innerException) : base(message, innerException) + { + } } } diff --git a/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs b/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs index 2a375b7d2..8b01e5ff5 100644 --- a/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs +++ b/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs @@ -3,12 +3,14 @@ namespace ICSharpCode.SharpZipLib.Core { #region EventArgs + /// /// Event arguments for scanning. /// public class ScanEventArgs : EventArgs { #region Constructors + /// /// Initialise a new instance of /// @@ -17,27 +19,32 @@ public ScanEventArgs(string name) { name_ = name; } - #endregion + + #endregion Constructors /// /// The file or directory name for this event. /// - public string Name { + public string Name + { get { return name_; } } /// /// Get set a value indicating if scanning should continue or not. /// - public bool ContinueRunning { + public bool ContinueRunning + { get { return continueRunning_; } set { continueRunning_ = value; } } #region Instance Fields - string name_; - bool continueRunning_ = true; - #endregion + + private string name_; + private bool continueRunning_ = true; + + #endregion Instance Fields } /// @@ -46,6 +53,7 @@ public bool ContinueRunning { public class ProgressEventArgs : EventArgs { #region Constructors + /// /// Initialise a new instance of /// @@ -58,19 +66,22 @@ public ProgressEventArgs(string name, long processed, long target) processed_ = processed; target_ = target; } - #endregion + + #endregion Constructors /// /// The name for this event if known. /// - public string Name { + public string Name + { get { return name_; } } /// /// Get set a value indicating wether scanning should continue or not. /// - public bool ContinueRunning { + public bool ContinueRunning + { get { return continueRunning_; } set { continueRunning_ = value; } } @@ -79,12 +90,17 @@ public bool ContinueRunning { /// Get a percentage representing how much of the has been processed /// /// 0.0 to 100.0 percent; 0 if target is not known. - public float PercentComplete { - get { + public float PercentComplete + { + get + { float result; - if (target_ <= 0) { + if (target_ <= 0) + { result = 0; - } else { + } + else + { result = ((float)processed_ / (float)target_) * 100.0f; } return result; @@ -94,7 +110,8 @@ public float PercentComplete { /// /// The number of bytes processed so far /// - public long Processed { + public long Processed + { get { return processed_; } } @@ -102,16 +119,19 @@ public long Processed { /// The number of bytes to process. /// /// Target may be 0 or negative if the value isnt known. - public long Target { + public long Target + { get { return target_; } } #region Instance Fields - string name_; - long processed_; - long target_; - bool continueRunning_ = true; - #endregion + + private string name_; + private long processed_; + private long target_; + private bool continueRunning_ = true; + + #endregion Instance Fields } /// @@ -120,6 +140,7 @@ public long Target { public class DirectoryEventArgs : ScanEventArgs { #region Constructors + /// /// Initialize an instance of . /// @@ -130,20 +151,24 @@ public DirectoryEventArgs(string name, bool hasMatchingFiles) { hasMatchingFiles_ = hasMatchingFiles; } - #endregion + + #endregion Constructors /// /// Get a value indicating if the directory contains any matching files or not. /// - public bool HasMatchingFiles { + public bool HasMatchingFiles + { get { return hasMatchingFiles_; } } - readonly + private readonly #region Instance Fields + bool hasMatchingFiles_; - #endregion + + #endregion Instance Fields } /// @@ -152,6 +177,7 @@ public bool HasMatchingFiles { public class ScanFailureEventArgs : EventArgs { #region Constructors + /// /// Initialise a new instance of /// @@ -163,40 +189,47 @@ public ScanFailureEventArgs(string name, Exception e) exception_ = e; continueRunning_ = true; } - #endregion + + #endregion Constructors /// /// The applicable name. /// - public string Name { + public string Name + { get { return name_; } } /// /// The applicable exception. /// - public Exception Exception { + public Exception Exception + { get { return exception_; } } /// /// Get / set a value indicating wether scanning should continue. /// - public bool ContinueRunning { + public bool ContinueRunning + { get { return continueRunning_; } set { continueRunning_ = value; } } #region Instance Fields - string name_; - Exception exception_; - bool continueRunning_; - #endregion + + private string name_; + private Exception exception_; + private bool continueRunning_; + + #endregion Instance Fields } - #endregion + #endregion EventArgs #region Delegates + /// /// Delegate invoked before starting to process a file. /// @@ -231,7 +264,8 @@ public bool ContinueRunning { /// The source of the event /// The event arguments. public delegate void FileFailureHandler(object sender, ScanFailureEventArgs e); - #endregion + + #endregion Delegates /// /// FileSystemScanner provides facilities scanning of files and directories. @@ -239,6 +273,7 @@ public bool ContinueRunning { public class FileSystemScanner { #region Constructors + /// /// Initialise a new instance of /// @@ -278,9 +313,11 @@ public FileSystemScanner(IScanFilter fileFilter, IScanFilter directoryFilter) fileFilter_ = fileFilter; directoryFilter_ = directoryFilter; } - #endregion + + #endregion Constructors #region Delegates + /// /// Delegate to invoke when a directory is processed. /// @@ -305,18 +342,20 @@ public FileSystemScanner(IScanFilter fileFilter, IScanFilter directoryFilter) /// Delegate to invoke when a file failure is detected. /// public FileFailureHandler FileFailure; - #endregion + + #endregion Delegates /// /// Raise the DirectoryFailure event. /// /// The directory name. /// The exception detected. - bool OnDirectoryFailure(string directory, Exception e) + private bool OnDirectoryFailure(string directory, Exception e) { DirectoryFailureHandler handler = DirectoryFailure; bool result = (handler != null); - if (result) { + if (result) + { var args = new ScanFailureEventArgs(directory, e); handler(this, args); alive_ = args.ContinueRunning; @@ -329,13 +368,14 @@ bool OnDirectoryFailure(string directory, Exception e) /// /// The file name. /// The exception detected. - bool OnFileFailure(string file, Exception e) + private bool OnFileFailure(string file, Exception e) { FileFailureHandler handler = FileFailure; bool result = (handler != null); - if (result) { + if (result) + { var args = new ScanFailureEventArgs(file, e); FileFailure(this, args); alive_ = args.ContinueRunning; @@ -347,11 +387,12 @@ bool OnFileFailure(string file, Exception e) /// Raise the ProcessFile event. /// /// The file name. - void OnProcessFile(string file) + private void OnProcessFile(string file) { ProcessFileHandler handler = ProcessFile; - if (handler != null) { + if (handler != null) + { var args = new ScanEventArgs(file); handler(this, args); alive_ = args.ContinueRunning; @@ -362,11 +403,12 @@ void OnProcessFile(string file) /// Raise the complete file event /// /// The file name - void OnCompleteFile(string file) + private void OnCompleteFile(string file) { CompletedFileHandler handler = CompletedFile; - if (handler != null) { + if (handler != null) + { var args = new ScanEventArgs(file); handler(this, args); alive_ = args.ContinueRunning; @@ -378,11 +420,12 @@ void OnCompleteFile(string file) /// /// The directory name. /// Flag indicating if the directory has matching files. - void OnProcessDirectory(string directory, bool hasMatchingFiles) + private void OnProcessDirectory(string directory, bool hasMatchingFiles) { EventHandler handler = ProcessDirectory; - if (handler != null) { + if (handler != null) + { var args = new DirectoryEventArgs(directory, hasMatchingFiles); handler(this, args); alive_ = args.ContinueRunning; @@ -400,57 +443,80 @@ public void Scan(string directory, bool recurse) ScanDir(directory, recurse); } - void ScanDir(string directory, bool recurse) + private void ScanDir(string directory, bool recurse) { - - try { + try + { string[] names = System.IO.Directory.GetFiles(directory); bool hasMatch = false; - for (int fileIndex = 0; fileIndex < names.Length; ++fileIndex) { - if (!fileFilter_.IsMatch(names[fileIndex])) { + for (int fileIndex = 0; fileIndex < names.Length; ++fileIndex) + { + if (!fileFilter_.IsMatch(names[fileIndex])) + { names[fileIndex] = null; - } else { + } + else + { hasMatch = true; } } OnProcessDirectory(directory, hasMatch); - if (alive_ && hasMatch) { - foreach (string fileName in names) { - try { - if (fileName != null) { + if (alive_ && hasMatch) + { + foreach (string fileName in names) + { + try + { + if (fileName != null) + { OnProcessFile(fileName); - if (!alive_) { + if (!alive_) + { break; } } - } catch (Exception e) { - if (!OnFileFailure(fileName, e)) { + } + catch (Exception e) + { + if (!OnFileFailure(fileName, e)) + { throw; } } } } - } catch (Exception e) { - if (!OnDirectoryFailure(directory, e)) { + } + catch (Exception e) + { + if (!OnDirectoryFailure(directory, e)) + { throw; } } - if (alive_ && recurse) { - try { + if (alive_ && recurse) + { + try + { string[] names = System.IO.Directory.GetDirectories(directory); - foreach (string fulldir in names) { - if ((directoryFilter_ == null) || (directoryFilter_.IsMatch(fulldir))) { + foreach (string fulldir in names) + { + if ((directoryFilter_ == null) || (directoryFilter_.IsMatch(fulldir))) + { ScanDir(fulldir, true); - if (!alive_) { + if (!alive_) + { break; } } } - } catch (Exception e) { - if (!OnDirectoryFailure(directory, e)) { + } + catch (Exception e) + { + if (!OnDirectoryFailure(directory, e)) + { throw; } } @@ -458,18 +524,22 @@ void ScanDir(string directory, bool recurse) } #region Instance Fields + /// /// The file filter currently in use. /// - IScanFilter fileFilter_; + private IScanFilter fileFilter_; + /// /// The directory filter currently in use. /// - IScanFilter directoryFilter_; + private IScanFilter directoryFilter_; + /// /// Flag indicating if scanning should continue running. /// - bool alive_; - #endregion + private bool alive_; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs b/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs index 99cc0e7e3..13abfd2f2 100644 --- a/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs @@ -1,19 +1,16 @@ using System; -using System.Collections.Generic; -using System.Text; namespace ICSharpCode.SharpZipLib.Core { - /// /// InvalidNameException is thrown for invalid names such as directory traversal paths and names with invalid characters /// - public class InvalidNameException: SharpZipBaseException - { + public class InvalidNameException : SharpZipBaseException + { /// /// Initializes a new instance of the InvalidNameException class with a default error message. /// - public InvalidNameException(): base("An invalid name was specified") + public InvalidNameException() : base("An invalid name was specified") { } diff --git a/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs b/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs index a2af22257..58c578a25 100644 --- a/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs +++ b/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; @@ -13,7 +12,7 @@ namespace ICSharpCode.SharpZipLib.Core /// To include a semi-colon it may be quoted as in \;. Each expression can be prefixed by a plus '+' sign or /// a minus '-' sign to denote the expression is intended to include or exclude names. /// If neither a plus or minus sign is found include is the default. - /// A given name is tested for inclusion before checking exclusions. Only names matching an include spec + /// A given name is tested for inclusion before checking exclusions. Only names matching an include spec /// and not matching an exclude spec are deemed to match the filter. /// An empty filter matches any name. /// @@ -23,6 +22,7 @@ namespace ICSharpCode.SharpZipLib.Core public class NameFilter : IScanFilter { #region Constructors + /// /// Construct an instance based on the filter expression passed /// @@ -34,7 +34,8 @@ public NameFilter(string filter) exclusions_ = new List(); Compile(); } - #endregion + + #endregion Constructors /// /// Test a string to see if it is a valid regular expression. @@ -44,9 +45,12 @@ public NameFilter(string filter) public static bool IsValidExpression(string expression) { bool result = true; - try { + try + { var exp = new Regex(expression, RegexOptions.IgnoreCase | RegexOptions.Singleline); - } catch (ArgumentException) { + } + catch (ArgumentException) + { result = false; } return result; @@ -61,18 +65,27 @@ public static bool IsValidFilterExpression(string toTest) { bool result = true; - try { - if (toTest != null) { + try + { + if (toTest != null) + { string[] items = SplitQuoted(toTest); - for (int i = 0; i < items.Length; ++i) { - if ((items[i] != null) && (items[i].Length > 0)) { + for (int i = 0; i < items.Length; ++i) + { + if ((items[i] != null) && (items[i].Length > 0)) + { string toCompile; - if (items[i][0] == '+') { + if (items[i][0] == '+') + { toCompile = items[i].Substring(1, items[i].Length - 1); - } else if (items[i][0] == '-') { + } + else if (items[i][0] == '-') + { toCompile = items[i].Substring(1, items[i].Length - 1); - } else { + } + else + { toCompile = items[i]; } @@ -80,7 +93,9 @@ public static bool IsValidFilterExpression(string toTest) } } } - } catch (ArgumentException) { + } + catch (ArgumentException) + { result = false; } @@ -99,17 +114,23 @@ public static string[] SplitQuoted(string original) var result = new List(); - if (!string.IsNullOrEmpty(original)) { + if (!string.IsNullOrEmpty(original)) + { int endIndex = -1; var b = new StringBuilder(); - while (endIndex < original.Length) { + while (endIndex < original.Length) + { endIndex += 1; - if (endIndex >= original.Length) { + if (endIndex >= original.Length) + { result.Add(b.ToString()); - } else if (original[endIndex] == escape) { + } + else if (original[endIndex] == escape) + { endIndex += 1; - if (endIndex >= original.Length) { + if (endIndex >= original.Length) + { throw new ArgumentException("Missing terminating escape character", nameof(original)); } // include escape if this is not an escaped separator @@ -117,11 +138,16 @@ public static string[] SplitQuoted(string original) b.Append(escape); b.Append(original[endIndex]); - } else { - if (Array.IndexOf(separators, original[endIndex]) >= 0) { + } + else + { + if (Array.IndexOf(separators, original[endIndex]) >= 0) + { result.Add(b.ToString()); b.Length = 0; - } else { + } + else + { b.Append(original[endIndex]); } } @@ -148,11 +174,16 @@ public override string ToString() public bool IsIncluded(string name) { bool result = false; - if (inclusions_.Count == 0) { + if (inclusions_.Count == 0) + { result = true; - } else { - foreach (Regex r in inclusions_) { - if (r.IsMatch(name)) { + } + else + { + foreach (Regex r in inclusions_) + { + if (r.IsMatch(name)) + { result = true; break; } @@ -169,8 +200,10 @@ public bool IsIncluded(string name) public bool IsExcluded(string name) { bool result = false; - foreach (Regex r in exclusions_) { - if (r.IsMatch(name)) { + foreach (Regex r in exclusions_) + { + if (r.IsMatch(name)) + { result = true; break; } @@ -179,6 +212,7 @@ public bool IsExcluded(string name) } #region IScanFilter Members + /// /// Test a value to see if it matches the filter. /// @@ -188,39 +222,51 @@ public bool IsMatch(string name) { return (IsIncluded(name) && !IsExcluded(name)); } - #endregion + + #endregion IScanFilter Members /// /// Compile this filter. /// - void Compile() + private void Compile() { // TODO: Check to see if combining RE's makes it faster/smaller. // simple scheme would be to have one RE for inclusion and one for exclusion. - if (filter_ == null) { + if (filter_ == null) + { return; } string[] items = SplitQuoted(filter_); - for (int i = 0; i < items.Length; ++i) { - if ((items[i] != null) && (items[i].Length > 0)) { + for (int i = 0; i < items.Length; ++i) + { + if ((items[i] != null) && (items[i].Length > 0)) + { bool include = (items[i][0] != '-'); string toCompile; - if (items[i][0] == '+') { + if (items[i][0] == '+') + { toCompile = items[i].Substring(1, items[i].Length - 1); - } else if (items[i][0] == '-') { + } + else if (items[i][0] == '-') + { toCompile = items[i].Substring(1, items[i].Length - 1); - } else { + } + else + { toCompile = items[i]; } // NOTE: Regular expressions can fail to compile here for a number of reasons that cause an exception // these are left unhandled here as the caller is responsible for ensuring all is valid. // several functions IsValidFilterExpression and IsValidExpression are provided for such checking - if (include) { + if (include) + { inclusions_.Add(new Regex(toCompile, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)); - } else { + } + else + { exclusions_.Add(new Regex(toCompile, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)); } } @@ -228,9 +274,11 @@ void Compile() } #region Instance Fields - string filter_; - List inclusions_; - List exclusions_; - #endregion + + private string filter_; + private List inclusions_; + private List exclusions_; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs b/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs index 76a40bdde..e70109c2c 100644 --- a/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs +++ b/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs @@ -11,6 +11,7 @@ namespace ICSharpCode.SharpZipLib.Core public class PathFilter : IScanFilter { #region Constructors + /// /// Initialise a new instance of . /// @@ -19,9 +20,11 @@ public PathFilter(string filter) { nameFilter_ = new NameFilter(filter); } - #endregion + + #endregion Constructors #region IScanFilter Members + /// /// Test a name to see if it matches the filter. /// @@ -32,19 +35,23 @@ public virtual bool IsMatch(string name) { bool result = false; - if (name != null) { + if (name != null) + { string cooked = (name.Length > 0) ? Path.GetFullPath(name) : ""; result = nameFilter_.IsMatch(cooked); } return result; } - readonly - #endregion + private readonly + + #endregion IScanFilter Members #region Instance Fields + NameFilter nameFilter_; - #endregion + + #endregion Instance Fields } /// @@ -54,6 +61,7 @@ public virtual bool IsMatch(string name) public class ExtendedPathFilter : PathFilter { #region Constructors + /// /// Initialise a new instance of ExtendedPathFilter. /// @@ -100,9 +108,11 @@ public ExtendedPathFilter(string filter, MinDate = minDate; MaxDate = maxDate; } - #endregion + + #endregion Constructors #region IScanFilter Members + /// /// Test a filename to see if it matches the filter. /// @@ -113,7 +123,8 @@ public override bool IsMatch(string name) { bool result = base.IsMatch(name); - if (result) { + if (result) + { var fileInfo = new FileInfo(name); result = (MinSize <= fileInfo.Length) && @@ -124,18 +135,23 @@ public override bool IsMatch(string name) } return result; } - #endregion + + #endregion IScanFilter Members #region Properties + /// /// Get/set the minimum size/length for a file that will match this filter. /// /// The default value is zero. /// value is less than zero; greater than - public long MinSize { + public long MinSize + { get { return minSize_; } - set { - if ((value < 0) || (maxSize_ < value)) { + set + { + if ((value < 0) || (maxSize_ < value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } @@ -148,10 +164,13 @@ public long MinSize { /// /// The default value is /// value is less than zero or less than - public long MaxSize { + public long MaxSize + { get { return maxSize_; } - set { - if ((value < 0) || (minSize_ > value)) { + set + { + if ((value < 0) || (minSize_ > value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } @@ -163,13 +182,17 @@ public long MaxSize { /// Get/set the minimum value that will match for this filter. /// /// Files with a LastWrite time less than this value are excluded by the filter. - public DateTime MinDate { - get { + public DateTime MinDate + { + get + { return minDate_; } - set { - if (value > maxDate_) { + set + { + if (value > maxDate_) + { throw new ArgumentOutOfRangeException(nameof(value), "Exceeds MaxDate"); } @@ -181,27 +204,34 @@ public DateTime MinDate { /// Get/set the maximum value that will match for this filter. /// /// Files with a LastWrite time greater than this value are excluded by the filter. - public DateTime MaxDate { - get { + public DateTime MaxDate + { + get + { return maxDate_; } - set { - if (minDate_ > value) { + set + { + if (minDate_ > value) + { throw new ArgumentOutOfRangeException(nameof(value), "Exceeds MinDate"); } maxDate_ = value; } } - #endregion + + #endregion Properties #region Instance Fields - long minSize_; - long maxSize_ = long.MaxValue; - DateTime minDate_ = DateTime.MinValue; - DateTime maxDate_ = DateTime.MaxValue; - #endregion + + private long minSize_; + private long maxSize_ = long.MaxValue; + private DateTime minDate_ = DateTime.MinValue; + private DateTime maxDate_ = DateTime.MaxValue; + + #endregion Instance Fields } /// @@ -211,7 +241,6 @@ public DateTime MaxDate { [Obsolete("Use ExtendedPathFilter instead")] public class NameAndSizeFilter : PathFilter { - /// /// Initialise a new instance of NameAndSizeFilter. /// @@ -234,7 +263,8 @@ public override bool IsMatch(string name) { bool result = base.IsMatch(name); - if (result) { + if (result) + { var fileInfo = new FileInfo(name); long length = fileInfo.Length; result = @@ -247,10 +277,13 @@ public override bool IsMatch(string name) /// /// Get/set the minimum size for a file that will match this filter. /// - public long MinSize { + public long MinSize + { get { return minSize_; } - set { - if ((value < 0) || (maxSize_ < value)) { + set + { + if ((value < 0) || (maxSize_ < value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } @@ -261,10 +294,13 @@ public long MinSize { /// /// Get/set the maximum size for a file that will match this filter. /// - public long MaxSize { + public long MaxSize + { get { return maxSize_; } - set { - if ((value < 0) || (minSize_ > value)) { + set + { + if ((value < 0) || (minSize_ > value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } @@ -273,8 +309,10 @@ public long MaxSize { } #region Instance Fields - long minSize_; - long maxSize_ = long.MaxValue; - #endregion + + private long minSize_; + private long maxSize_ = long.MaxValue; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs b/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs index 2f150adbb..348fe68de 100644 --- a/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs +++ b/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs @@ -31,26 +31,32 @@ static public void ReadFully(Stream stream, byte[] buffer) /// End of stream is encountered before all the data has been read. static public void ReadFully(Stream stream, byte[] buffer, int offset, int count) { - if (stream == null) { + if (stream == null) + { throw new ArgumentNullException(nameof(stream)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } // Offset can equal length when buffer and count are 0. - if ((offset < 0) || (offset > buffer.Length)) { + if ((offset < 0) || (offset > buffer.Length)) + { throw new ArgumentOutOfRangeException(nameof(offset)); } - if ((count < 0) || (offset + count > buffer.Length)) { + if ((count < 0) || (offset + count > buffer.Length)) + { throw new ArgumentOutOfRangeException(nameof(count)); } - while (count > 0) { + while (count > 0) + { int readCount = stream.Read(buffer, offset, count); - if (readCount <= 0) { + if (readCount <= 0) + { throw new EndOfStreamException(); } offset += readCount; @@ -66,30 +72,38 @@ static public void ReadFully(Stream stream, byte[] buffer, int offset, int count /// The buffer to use during copying. static public void Copy(Stream source, Stream destination, byte[] buffer) { - if (source == null) { + if (source == null) + { throw new ArgumentNullException(nameof(source)); } - if (destination == null) { + if (destination == null) + { throw new ArgumentNullException(nameof(destination)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } // Ensure a reasonable size of buffer is used without being prohibitive. - if (buffer.Length < 128) { + if (buffer.Length < 128) + { throw new ArgumentException("Buffer is too small", nameof(buffer)); } bool copying = true; - while (copying) { + while (copying) + { int bytesRead = source.Read(buffer, 0, buffer.Length); - if (bytesRead > 0) { + if (bytesRead > 0) + { destination.Write(buffer, 0, bytesRead); - } else { + } + else + { destination.Flush(); copying = false; } @@ -131,24 +145,29 @@ static public void Copy(Stream source, Stream destination, ProgressHandler progressHandler, TimeSpan updateInterval, object sender, string name, long fixedTarget) { - if (source == null) { + if (source == null) + { throw new ArgumentNullException(nameof(source)); } - if (destination == null) { + if (destination == null) + { throw new ArgumentNullException(nameof(destination)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } // Ensure a reasonable size of buffer is used without being prohibitive. - if (buffer.Length < 128) { + if (buffer.Length < 128) + { throw new ArgumentException("Buffer is too small", nameof(buffer)); } - if (progressHandler == null) { + if (progressHandler == null) + { throw new ArgumentNullException(nameof(progressHandler)); } @@ -158,9 +177,12 @@ static public void Copy(Stream source, Stream destination, long processed = 0; long target = 0; - if (fixedTarget >= 0) { + if (fixedTarget >= 0) + { target = fixedTarget; - } else if (source.CanSeek) { + } + else if (source.CanSeek) + { target = source.Length - source.Position; } @@ -170,18 +192,23 @@ static public void Copy(Stream source, Stream destination, bool progressFired = true; - while (copying) { + while (copying) + { int bytesRead = source.Read(buffer, 0, buffer.Length); - if (bytesRead > 0) { + if (bytesRead > 0) + { processed += bytesRead; progressFired = false; destination.Write(buffer, 0, bytesRead); - } else { + } + else + { destination.Flush(); copying = false; } - if (DateTime.Now - marker > updateInterval) { + if (DateTime.Now - marker > updateInterval) + { progressFired = true; marker = DateTime.Now; args = new ProgressEventArgs(name, processed, target); @@ -191,7 +218,8 @@ static public void Copy(Stream source, Stream destination, } } - if (!progressFired) { + if (!progressFired) + { args = new ProgressEventArgs(name, processed, target); progressHandler(sender, args); } diff --git a/src/ICSharpCode.SharpZipLib/Core/WindowsPathUtils.cs b/src/ICSharpCode.SharpZipLib/Core/WindowsPathUtils.cs index d771b3731..f02a0affb 100644 --- a/src/ICSharpCode.SharpZipLib/Core/WindowsPathUtils.cs +++ b/src/ICSharpCode.SharpZipLib/Core/WindowsPathUtils.cs @@ -22,30 +22,40 @@ public static string DropPathRoot(string path) { string result = path; - if (!string.IsNullOrEmpty(path)) { - if ((path[0] == '\\') || (path[0] == '/')) { + if (!string.IsNullOrEmpty(path)) + { + if ((path[0] == '\\') || (path[0] == '/')) + { // UNC name ? - if ((path.Length > 1) && ((path[1] == '\\') || (path[1] == '/'))) { + if ((path.Length > 1) && ((path[1] == '\\') || (path[1] == '/'))) + { int index = 2; int elements = 2; // Scan for two separate elements \\machine\share\restofpath while ((index <= path.Length) && - (((path[index] != '\\') && (path[index] != '/')) || (--elements > 0))) { + (((path[index] != '\\') && (path[index] != '/')) || (--elements > 0))) + { index++; } index++; - if (index < path.Length) { + if (index < path.Length) + { result = path.Substring(index); - } else { + } + else + { result = ""; } } - } else if ((path.Length > 1) && (path[1] == ':')) { + } + else if ((path.Length > 1) && (path[1] == ':')) + { int dropCount = 2; - if ((path.Length > 2) && ((path[2] == '\\') || (path[2] == '/'))) { + if ((path.Length > 2) && ((path[2] == '\\') || (path[2] == '/'))) + { dropCount = 3; } result = result.Remove(0, dropCount); diff --git a/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs b/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs index 8c1c7517c..7a8c55e6e 100644 --- a/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs +++ b/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs @@ -1,12 +1,12 @@ +using ICSharpCode.SharpZipLib.Checksum; using System; using System.Security.Cryptography; -using ICSharpCode.SharpZipLib.Checksum; namespace ICSharpCode.SharpZipLib.Encryption { /// /// PkzipClassic embodies the classic or original encryption facilities used in Pkzip archives. - /// While it has been superceded by more recent and more powerful algorithms, its still in use and + /// While it has been superceded by more recent and more powerful algorithms, its still in use and /// is viable for preventing casual snooping /// public abstract class PkzipClassic : SymmetricAlgorithm @@ -18,11 +18,13 @@ public abstract class PkzipClassic : SymmetricAlgorithm /// A new key value. static public byte[] GenerateKeys(byte[] seed) { - if (seed == null) { + if (seed == null) + { throw new ArgumentNullException(nameof(seed)); } - if (seed.Length == 0) { + if (seed.Length == 0) + { throw new ArgumentException("Length is zero", nameof(seed)); } @@ -32,7 +34,8 @@ static public byte[] GenerateKeys(byte[] seed) 0x34567890 }; - for (int i = 0; i < seed.Length; ++i) { + for (int i = 0; i < seed.Length; ++i) + { newKeys[0] = Crc32.ComputeCrc32(newKeys[0], seed[i]); newKeys[1] = newKeys[1] + (byte)newKeys[0]; newKeys[1] = newKeys[1] * 134775813 + 1; @@ -60,10 +63,10 @@ static public byte[] GenerateKeys(byte[] seed) /// PkzipClassicCryptoBase provides the low level facilities for encryption /// and decryption using the PkzipClassic algorithm. /// - class PkzipClassicCryptoBase + internal class PkzipClassicCryptoBase { /// - /// Transform a single byte + /// Transform a single byte /// /// /// The transformed value @@ -80,11 +83,13 @@ protected byte TransformByte() /// The data use to set the keys from. protected void SetKeys(byte[] keyData) { - if (keyData == null) { + if (keyData == null) + { throw new ArgumentNullException(nameof(keyData)); } - if (keyData.Length != 12) { + if (keyData.Length != 12) + { throw new InvalidOperationException("Key length is not valid"); } @@ -95,8 +100,8 @@ protected void SetKeys(byte[] keyData) } /// - /// Update encryption keys - /// + /// Update encryption keys + /// protected void UpdateKeys(byte ch) { keys[0] = Crc32.ComputeCrc32(keys[0], ch); @@ -116,14 +121,16 @@ protected void Reset() } #region Instance Fields - uint[] keys; - #endregion + + private uint[] keys; + + #endregion Instance Fields } /// /// PkzipClassic CryptoTransform for encryption. /// - class PkzipClassicEncryptCryptoTransform : PkzipClassicCryptoBase, ICryptoTransform + internal class PkzipClassicEncryptCryptoTransform : PkzipClassicCryptoBase, ICryptoTransform { /// /// Initialise a new instance of @@ -151,7 +158,7 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input } /// - /// Transforms the specified region of the input byte array and copies + /// Transforms the specified region of the input byte array and copies /// the resulting transform to the specified region of the output byte array. /// /// The input for which to compute the transform. @@ -162,7 +169,8 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input /// The number of bytes written. public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { - for (int i = inputOffset; i < inputOffset + inputCount; ++i) { + for (int i = inputOffset; i < inputOffset + inputCount; ++i) + { byte oldbyte = inputBuffer[i]; outputBuffer[outputOffset++] = (byte)(inputBuffer[i] ^ TransformByte()); UpdateKeys(oldbyte); @@ -173,8 +181,10 @@ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, b /// /// Gets a value indicating whether the current transform can be reused. /// - public bool CanReuseTransform { - get { + public bool CanReuseTransform + { + get + { return true; } } @@ -182,8 +192,10 @@ public bool CanReuseTransform { /// /// Gets the size of the input data blocks in bytes. /// - public int InputBlockSize { - get { + public int InputBlockSize + { + get + { return 1; } } @@ -191,8 +203,10 @@ public int InputBlockSize { /// /// Gets the size of the output data blocks in bytes. /// - public int OutputBlockSize { - get { + public int OutputBlockSize + { + get + { return 1; } } @@ -200,13 +214,15 @@ public int OutputBlockSize { /// /// Gets a value indicating whether multiple blocks can be transformed. /// - public bool CanTransformMultipleBlocks { - get { + public bool CanTransformMultipleBlocks + { + get + { return true; } } - #endregion + #endregion ICryptoTransform Members #region IDisposable Members @@ -218,14 +234,13 @@ public void Dispose() Reset(); } - #endregion + #endregion IDisposable Members } - /// /// PkzipClassic CryptoTransform for decryption. /// - class PkzipClassicDecryptCryptoTransform : PkzipClassicCryptoBase, ICryptoTransform + internal class PkzipClassicDecryptCryptoTransform : PkzipClassicCryptoBase, ICryptoTransform { /// /// Initialise a new instance of . @@ -253,7 +268,7 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input } /// - /// Transforms the specified region of the input byte array and copies + /// Transforms the specified region of the input byte array and copies /// the resulting transform to the specified region of the output byte array. /// /// The input for which to compute the transform. @@ -264,7 +279,8 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input /// The number of bytes written. public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { - for (int i = inputOffset; i < inputOffset + inputCount; ++i) { + for (int i = inputOffset; i < inputOffset + inputCount; ++i) + { var newByte = (byte)(inputBuffer[i] ^ TransformByte()); outputBuffer[outputOffset++] = newByte; UpdateKeys(newByte); @@ -275,8 +291,10 @@ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, b /// /// Gets a value indicating whether the current transform can be reused. /// - public bool CanReuseTransform { - get { + public bool CanReuseTransform + { + get + { return true; } } @@ -284,8 +302,10 @@ public bool CanReuseTransform { /// /// Gets the size of the input data blocks in bytes. /// - public int InputBlockSize { - get { + public int InputBlockSize + { + get + { return 1; } } @@ -293,8 +313,10 @@ public int InputBlockSize { /// /// Gets the size of the output data blocks in bytes. /// - public int OutputBlockSize { - get { + public int OutputBlockSize + { + get + { return 1; } } @@ -302,13 +324,15 @@ public int OutputBlockSize { /// /// Gets a value indicating whether multiple blocks can be transformed. /// - public bool CanTransformMultipleBlocks { - get { + public bool CanTransformMultipleBlocks + { + get + { return true; } } - #endregion + #endregion ICryptoTransform Members #region IDisposable Members @@ -320,11 +344,11 @@ public void Dispose() Reset(); } - #endregion + #endregion IDisposable Members } /// - /// Defines a wrapper object to access the Pkzip algorithm. + /// Defines a wrapper object to access the Pkzip algorithm. /// This class cannot be inherited. /// public sealed class PkzipClassicManaged : PkzipClassic @@ -333,13 +357,17 @@ public sealed class PkzipClassicManaged : PkzipClassic /// Get / set the applicable block size in bits. /// /// The only valid block size is 8. - public override int BlockSize { - get { + public override int BlockSize + { + get + { return 8; } - set { - if (value != 8) { + set + { + if (value != 8) + { throw new CryptographicException("Block size is invalid"); } } @@ -348,8 +376,10 @@ public override int BlockSize { /// /// Get an array of legal key sizes. /// - public override KeySizes[] LegalKeySizes { - get { + public override KeySizes[] LegalKeySizes + { + get + { KeySizes[] keySizes = new KeySizes[1]; keySizes[0] = new KeySizes(12 * 8, 12 * 8, 0); return keySizes; @@ -367,8 +397,10 @@ public override void GenerateIV() /// /// Get an array of legal block sizes. /// - public override KeySizes[] LegalBlockSizes { - get { + public override KeySizes[] LegalBlockSizes + { + get + { KeySizes[] keySizes = new KeySizes[1]; keySizes[0] = new KeySizes(1 * 8, 1 * 8, 0); return keySizes; @@ -378,21 +410,27 @@ public override KeySizes[] LegalBlockSizes { /// /// Get / set the key value applicable. /// - public override byte[] Key { - get { - if (key_ == null) { + public override byte[] Key + { + get + { + if (key_ == null) + { GenerateKey(); } return (byte[])key_.Clone(); } - set { - if (value == null) { + set + { + if (value == null) + { throw new ArgumentNullException(nameof(value)); } - if (value.Length != 12) { + if (value.Length != 12) + { throw new CryptographicException("Key size is illegal"); } @@ -439,7 +477,9 @@ public override ICryptoTransform CreateDecryptor( } #region Instance Fields - byte[] key_; - #endregion + + private byte[] key_; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs index 18e7ec6a9..dc16a7c4d 100644 --- a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs +++ b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs @@ -13,7 +13,6 @@ namespace ICSharpCode.SharpZipLib.Encryption /// internal class ZipAESStream : CryptoStream { - /// /// Constructor /// @@ -23,7 +22,6 @@ internal class ZipAESStream : CryptoStream public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode mode) : base(stream, transform, mode) { - _stream = stream; _transform = transform; _slideBuffer = new byte[1024]; @@ -33,7 +31,8 @@ public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode m // mode: // CryptoStreamMode.Read means we read from "stream" and pass decrypted to our Read() method. // Write bypasses this stream and uses the Transform directly. - if (mode != CryptoStreamMode.Read) { + if (mode != CryptoStreamMode.Read) + { throw new Exception("ZipAESStream only for read"); } } @@ -46,8 +45,10 @@ public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode m private byte[] _slideBuffer; private int _slideBufStartPos; private int _slideBufFreePos; + // Blocksize is always 16 here, even for AES-256 which has transform.InputBlockSize of 32. private const int CRYPTO_BLOCK_SIZE = 16; + private int _blockAndAuth; /// @@ -57,18 +58,21 @@ public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode m public override int Read(byte[] buffer, int offset, int count) { int nBytes = 0; - while (nBytes < count) { + while (nBytes < count) + { // Calculate buffer quantities vs read-ahead size, and check for sufficient free space int byteCount = _slideBufFreePos - _slideBufStartPos; // Need to handle final block and Auth Code specially, but don't know total data length. - // Maintain a read-ahead equal to the length of (crypto block + Auth Code). + // Maintain a read-ahead equal to the length of (crypto block + Auth Code). // When that runs out we can detect these final sections. int lengthToRead = _blockAndAuth - byteCount; - if (_slideBuffer.Length - _slideBufFreePos < lengthToRead) { + if (_slideBuffer.Length - _slideBufFreePos < lengthToRead) + { // Shift the data to the beginning of the buffer int iTo = 0; - for (int iFrom = _slideBufStartPos; iFrom < _slideBufFreePos; iFrom++, iTo++) { + for (int iFrom = _slideBufStartPos; iFrom < _slideBufFreePos; iFrom++, iTo++) + { _slideBuffer[iTo] = _slideBuffer[iFrom]; } _slideBufFreePos -= _slideBufStartPos; // Note the -= @@ -79,7 +83,8 @@ public override int Read(byte[] buffer, int offset, int count) // Recalculate how much data we now have byteCount = _slideBufFreePos - _slideBufStartPos; - if (byteCount >= _blockAndAuth) { + if (byteCount >= _blockAndAuth) + { // At least a 16 byte block and an auth code remains. _transform.TransformBlock(_slideBuffer, _slideBufStartPos, @@ -89,9 +94,12 @@ public override int Read(byte[] buffer, int offset, int count) nBytes += CRYPTO_BLOCK_SIZE; offset += CRYPTO_BLOCK_SIZE; _slideBufStartPos += CRYPTO_BLOCK_SIZE; - } else { + } + else + { // Last round. - if (byteCount > AUTH_CODE_LENGTH) { + if (byteCount > AUTH_CODE_LENGTH) + { // At least one byte of data plus auth code int finalBlock = byteCount - AUTH_CODE_LENGTH; _transform.TransformBlock(_slideBuffer, @@ -102,12 +110,15 @@ public override int Read(byte[] buffer, int offset, int count) nBytes += finalBlock; _slideBufStartPos += finalBlock; - } else if (byteCount < AUTH_CODE_LENGTH) + } + else if (byteCount < AUTH_CODE_LENGTH) throw new Exception("Internal error missed auth code"); // Coding bug // Final block done. Check Auth code. byte[] calcAuthCode = _transform.GetAuthCode(); - for (int i = 0; i < AUTH_CODE_LENGTH; i++) { - if (calcAuthCode[i] != _slideBuffer[_slideBufStartPos + i]) { + for (int i = 0; i < AUTH_CODE_LENGTH; i++) + { + if (calcAuthCode[i] != _slideBuffer[_slideBufStartPos + i]) + { throw new Exception("AES Authentication Code does not match. This is a super-CRC check on the data in the file after compression and encryption. \r\n" + "The file may be damaged."); } diff --git a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs index 81c4a4481..80394a93a 100644 --- a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs +++ b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs @@ -8,7 +8,6 @@ namespace ICSharpCode.SharpZipLib.Encryption /// internal class ZipAESTransform : ICryptoTransform { - #if NET45 class IncrementalHash : HMACSHA1 { @@ -66,7 +65,6 @@ static class HashAlgorithmName /// public ZipAESTransform(string key, byte[] saltBytes, int blockSize, bool writeMode) { - if (blockSize != 16 && blockSize != 32) // 24 valid for AES but not supported by Winzip throw new Exception("Invalid blocksize " + blockSize + ". Must be 16 or 32."); if (saltBytes.Length != blockSize / 2) @@ -83,7 +81,7 @@ public ZipAESTransform(string key, byte[] saltBytes, int blockSize, bool writeMo _counterNonce = new byte[_blockSize]; byte[] key1bytes = pdb.GetBytes(_blockSize); byte[] key2bytes = pdb.GetBytes(_blockSize); - + // Use empty IV for AES _encryptor = rm.CreateEncryptor(key1bytes, new byte[16]); _pwdVerifier = pdb.GetBytes(PWD_VER_LENGTH); @@ -97,19 +95,22 @@ public ZipAESTransform(string key, byte[] saltBytes, int blockSize, bool writeMo /// public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { - // Pass the data stream to the hash algorithm for generating the Auth Code. // This does not change the inputBuffer. Do this before decryption for read mode. - if (!_writeMode) { + if (!_writeMode) + { _hmacsha1.AppendData(inputBuffer, inputOffset, inputCount); } // Encrypt with AES in CTR mode. Regards to Dr Brian Gladman for this. int ix = 0; - while (ix < inputCount) { - if (_encrPos == ENCRYPT_BLOCK) { + while (ix < inputCount) + { + if (_encrPos == ENCRYPT_BLOCK) + { /* increment encryption nonce */ int j = 0; - while (++_counterNonce[j] == 0) { + while (++_counterNonce[j] == 0) + { ++j; } /* encrypt the nonce to form next xor buffer */ @@ -120,8 +121,9 @@ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, b // ix++; } - if (_writeMode) { - // This does not change the buffer. + if (_writeMode) + { + // This does not change the buffer. _hmacsha1.AppendData(outputBuffer, outputOffset, inputCount); } return inputCount; @@ -130,8 +132,10 @@ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, b /// /// Returns the 2 byte password verifier /// - public byte[] PwdVerifier { - get { + public byte[] PwdVerifier + { + get + { return _pwdVerifier; } } @@ -148,22 +152,23 @@ public byte[] GetAuthCode() return _authCode; } -#region ICryptoTransform Members + #region ICryptoTransform Members /// /// Not implemented. /// public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { - throw new NotImplementedException("ZipAESTransform.TransformFinalBlock"); } /// /// Gets the size of the input data blocks in bytes. /// - public int InputBlockSize { - get { + public int InputBlockSize + { + get + { return _blockSize; } } @@ -171,8 +176,10 @@ public int InputBlockSize { /// /// Gets the size of the output data blocks in bytes. /// - public int OutputBlockSize { - get { + public int OutputBlockSize + { + get + { return _blockSize; } } @@ -180,8 +187,10 @@ public int OutputBlockSize { /// /// Gets a value indicating whether multiple blocks can be transformed. /// - public bool CanTransformMultipleBlocks { - get { + public bool CanTransformMultipleBlocks + { + get + { return true; } } @@ -189,8 +198,10 @@ public bool CanTransformMultipleBlocks { /// /// Gets a value indicating whether the current transform can be reused. /// - public bool CanReuseTransform { - get { + public bool CanReuseTransform + { + get + { return true; } } @@ -203,7 +214,6 @@ public void Dispose() _encryptor.Dispose(); } -#endregion - + #endregion ICryptoTransform Members } } diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs index f3970bba7..e7e4763da 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs @@ -11,7 +11,7 @@ namespace ICSharpCode.SharpZipLib.GZip public static class GZip { /// - /// Decompress the input writing + /// Decompress the input writing /// uncompressed data to the output stream /// /// The readable stream containing data to decompress. @@ -45,7 +45,7 @@ public static void Decompress(Stream inStream, Stream outStream, bool isStreamOw } /// - /// Compress the input stream sending + /// Compress the input stream sending /// result data to output stream /// /// The readable stream to compress. @@ -61,13 +61,13 @@ public static void Compress(Stream inStream, Stream outStream, bool isStreamOwne if (inStream == null) throw new ArgumentNullException(nameof(inStream), "Input stream is null"); - if(outStream == null) + if (outStream == null) throw new ArgumentNullException(nameof(outStream), "Output stream is null"); if (bufferSize < 512) throw new ArgumentOutOfRangeException(nameof(bufferSize), "Deflate buffer size must be >= 512"); - if (level BEST_COMPRESSION) + if (level < NO_COMPRESSION || level > BEST_COMPRESSION) throw new ArgumentOutOfRangeException(nameof(level), "Compression level must be 0-9"); try @@ -88,6 +88,5 @@ public static void Compress(Stream inStream, Stream outStream, bool isStreamOwne } } } - } } diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZipConstants.cs b/src/ICSharpCode.SharpZipLib/GZip/GZipConstants.cs index 747d71a54..422cd97a4 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZipConstants.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZipConstants.cs @@ -11,7 +11,7 @@ sealed public class GZipConstants public const int GZIP_MAGIC = 0x1F8B; /* The flag byte is divided into individual bits as follows: - + bit 0 FTEXT bit 1 FHCRC bit 2 FEXTRA @@ -51,7 +51,7 @@ bit 7 reserved /// Initialise default instance. /// /// Constructor is private to prevent instances being created. - GZipConstants() + private GZipConstants() { } } diff --git a/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs b/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs index 911b1e00c..be10e85c9 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs @@ -1,26 +1,25 @@ -using System; -using System.IO; using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Zip.Compression; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.GZip { - /// /// This filter stream is used to decompress a "GZIP" format stream. /// The "GZIP" format is described baseInputStream RFC 1952. - /// + /// /// author of the original java version : John Leuner /// /// This sample shows how to unzip a gzipped file /// /// using System; /// using System.IO; - /// + /// /// using ICSharpCode.SharpZipLib.Core; /// using ICSharpCode.SharpZipLib.GZip; - /// + /// /// class MainClass /// { /// public static void Main(string[] args) @@ -31,12 +30,13 @@ namespace ICSharpCode.SharpZipLib.GZip /// StreamUtils.Copy(inStream, outStream, buffer); /// } /// } - /// } + /// } /// /// public class GZipInputStream : InflaterInputStream { #region Instance Fields + /// /// CRC-32 value for uncompressed data /// @@ -46,16 +46,18 @@ public class GZipInputStream : InflaterInputStream /// Flag to indicate if we've read the GZIP header yet for the current member (block of compressed data). /// This is tracked per-block as the file is parsed. /// - bool readGZIPHeader; + private bool readGZIPHeader; - /// - /// Flag to indicate if at least one block in a stream with concatenated blocks was read successfully. - /// This allows us to exit gracefully if downstream data is not in gzip format. - /// - bool completedLastBlock; - #endregion + /// + /// Flag to indicate if at least one block in a stream with concatenated blocks was read successfully. + /// This allows us to exit gracefully if downstream data is not in gzip format. + /// + private bool completedLastBlock; + + #endregion Instance Fields #region Constructors + /// /// Creates a GZipInputStream with the default buffer size /// @@ -80,9 +82,11 @@ public GZipInputStream(Stream baseInputStream, int size) : base(baseInputStream, new Inflater(true), size) { } - #endregion + + #endregion Constructors #region Stream overrides + /// /// Reads uncompressed data into an array of bytes /// @@ -101,58 +105,65 @@ public override int Read(byte[] buffer, int offset, int count) // A GZIP file can contain multiple blocks of compressed data, although this is quite rare. // A compressed block could potentially be empty, so we need to loop until we reach EOF or // we find data. - while (true) { - + while (true) + { // If we haven't read the header for this block, read it - if (!readGZIPHeader) { - - // Try to read header. If there is no header (0 bytes available), this is EOF. If there is - // an incomplete header, this will throw an exception. - try - { - if (!ReadHeader()) - { - return 0; - } - } - catch (Exception ex) when (completedLastBlock && (ex is GZipException || ex is EndOfStreamException)) - { - // if we completed the last block (i.e. we're in a stream that has multiple blocks concatenated - // we want to return gracefully from any header parsing exceptions since sometimes there may - // be trailing garbage on a stream - return 0; - } - } + if (!readGZIPHeader) + { + // Try to read header. If there is no header (0 bytes available), this is EOF. If there is + // an incomplete header, this will throw an exception. + try + { + if (!ReadHeader()) + { + return 0; + } + } + catch (Exception ex) when (completedLastBlock && (ex is GZipException || ex is EndOfStreamException)) + { + // if we completed the last block (i.e. we're in a stream that has multiple blocks concatenated + // we want to return gracefully from any header parsing exceptions since sometimes there may + // be trailing garbage on a stream + return 0; + } + } // Try to read compressed data int bytesRead = base.Read(buffer, offset, count); - if (bytesRead > 0) { + if (bytesRead > 0) + { crc.Update(new ArraySegment(buffer, offset, bytesRead)); } // If this is the end of stream, read the footer - if (inf.IsFinished) { + if (inf.IsFinished) + { ReadFooter(); } - if (bytesRead > 0) { + if (bytesRead > 0) + { return bytesRead; } } } - #endregion + + #endregion Stream overrides #region Support routines - bool ReadHeader() + + private bool ReadHeader() { // Initialize CRC for this block crc = new Crc32(); // Make sure there is data in file. We can't rely on ReadLeByte() to fill the buffer, as this could be EOF, // which is fine, but ReadLeByte() throws an exception if it doesn't find data, so we do this part ourselves. - if (inputBuffer.Available <= 0) { + if (inputBuffer.Available <= 0) + { inputBuffer.Fill(); - if (inputBuffer.Available <= 0) { + if (inputBuffer.Available <= 0) + { // No header, EOF. return false; } @@ -162,23 +173,27 @@ bool ReadHeader() var headCRC = new Crc32(); int magic = inputBuffer.ReadLeByte(); - if (magic < 0) { + if (magic < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(magic); - if (magic != (GZipConstants.GZIP_MAGIC >> 8)) { - throw new GZipException("Error GZIP header, first magic byte doesn't match"); + if (magic != (GZipConstants.GZIP_MAGIC >> 8)) + { + throw new GZipException("Error GZIP header, first magic byte doesn't match"); } //magic = baseInputStream.ReadByte(); magic = inputBuffer.ReadLeByte(); - if (magic < 0) { - throw new EndOfStreamException("EOS reading GZIP header"); + if (magic < 0) + { + throw new EndOfStreamException("EOS reading GZIP header"); } - if (magic != (GZipConstants.GZIP_MAGIC & 0xFF)) { + if (magic != (GZipConstants.GZIP_MAGIC & 0xFF)) + { throw new GZipException("Error GZIP header, second magic byte doesn't match"); } @@ -187,18 +202,21 @@ bool ReadHeader() // 2. Check the compression type (must be 8) int compressionType = inputBuffer.ReadLeByte(); - if (compressionType < 0) { + if (compressionType < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } - if (compressionType != 8) { + if (compressionType != 8) + { throw new GZipException("Error GZIP header, data not in deflate format"); } headCRC.Update(compressionType); // 3. Check the flags int flags = inputBuffer.ReadLeByte(); - if (flags < 0) { + if (flags < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(flags); @@ -217,36 +235,42 @@ bit 7 reserved // 3.1 Check the reserved bits are zero - if ((flags & 0xE0) != 0) { + if ((flags & 0xE0) != 0) + { throw new GZipException("Reserved flag bits in GZIP header != 0"); } // 4.-6. Skip the modification time, extra flags, and OS type - for (int i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) + { int readByte = inputBuffer.ReadLeByte(); - if (readByte < 0) { + if (readByte < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 7. Read extra field - if ((flags & GZipConstants.FEXTRA) != 0) { - + if ((flags & GZipConstants.FEXTRA) != 0) + { // XLEN is total length of extra subfields, we will skip them all int len1, len2; len1 = inputBuffer.ReadLeByte(); len2 = inputBuffer.ReadLeByte(); - if ((len1 < 0) || (len2 < 0)) { + if ((len1 < 0) || (len2 < 0)) + { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(len1); headCRC.Update(len2); int extraLen = (len2 << 8) | len1; // gzip is LSB first - for (int i = 0; i < extraLen; i++) { + for (int i = 0; i < extraLen; i++) + { int readByte = inputBuffer.ReadLeByte(); - if (readByte < 0) { + if (readByte < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); @@ -254,26 +278,32 @@ bit 7 reserved } // 8. Read file name - if ((flags & GZipConstants.FNAME) != 0) { + if ((flags & GZipConstants.FNAME) != 0) + { int readByte; - while ((readByte = inputBuffer.ReadLeByte()) > 0) { + while ((readByte = inputBuffer.ReadLeByte()) > 0) + { headCRC.Update(readByte); } - if (readByte < 0) { + if (readByte < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 9. Read comment - if ((flags & GZipConstants.FCOMMENT) != 0) { + if ((flags & GZipConstants.FCOMMENT) != 0) + { int readByte; - while ((readByte = inputBuffer.ReadLeByte()) > 0) { + while ((readByte = inputBuffer.ReadLeByte()) > 0) + { headCRC.Update(readByte); } - if (readByte < 0) { + if (readByte < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } @@ -281,20 +311,24 @@ bit 7 reserved } // 10. Read header CRC - if ((flags & GZipConstants.FHCRC) != 0) { + if ((flags & GZipConstants.FHCRC) != 0) + { int tempByte; int crcval = inputBuffer.ReadLeByte(); - if (crcval < 0) { + if (crcval < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } tempByte = inputBuffer.ReadLeByte(); - if (tempByte < 0) { + if (tempByte < 0) + { throw new EndOfStreamException("EOS reading GZIP header"); } crcval = (crcval << 8) | tempByte; - if (crcval != ((int)headCRC.Value & 0xffff)) { + if (crcval != ((int)headCRC.Value & 0xffff)) + { throw new GZipException("Header CRC value mismatch"); } } @@ -303,7 +337,7 @@ bit 7 reserved return true; } - void ReadFooter() + private void ReadFooter() { byte[] footer = new byte[8]; @@ -314,9 +348,11 @@ void ReadFooter() // Read footer from inputBuffer int needed = 8; - while (needed > 0) { + while (needed > 0) + { int count = inputBuffer.ReadClearTextBuffer(footer, 8 - needed, needed); - if (count <= 0) { + if (count <= 0) + { throw new EndOfStreamException("EOS reading GZIP footer"); } needed -= count; // Jewel Jan 16 @@ -324,7 +360,8 @@ void ReadFooter() // Calculate CRC int crcval = (footer[0] & 0xff) | ((footer[1] & 0xff) << 8) | ((footer[2] & 0xff) << 16) | (footer[3] << 24); - if (crcval != (int)crc.Value) { + if (crcval != (int)crc.Value) + { throw new GZipException("GZIP crc sum mismatch, theirs \"" + crcval + "\" and ours \"" + (int)crc.Value); } @@ -335,16 +372,18 @@ void ReadFooter() (uint)(((uint)footer[6] & 0xff) << 16) | (uint)((uint)footer[7] << 24); - if (bytesRead != total) { + if (bytesRead != total) + { throw new GZipException("Number of bytes mismatch in footer"); } // Mark header read as false so if another header exists, we'll continue reading through the file readGZIPHeader = false; - // Indicate that we succeeded on at least one block so we can exit gracefully if there is trailing garbage downstream - completedLastBlock = true; + // Indicate that we succeeded on at least one block so we can exit gracefully if there is trailing garbage downstream + completedLastBlock = true; } - #endregion + + #endregion Support routines } } diff --git a/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs b/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs index 2336d0496..3079b04aa 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GzipOutputStream.cs @@ -1,8 +1,8 @@ -using System; -using System.IO; using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Zip.Compression; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.GZip { @@ -16,10 +16,10 @@ namespace ICSharpCode.SharpZipLib.GZip /// /// using System; /// using System.IO; - /// + /// /// using ICSharpCode.SharpZipLib.GZip; /// using ICSharpCode.SharpZipLib.Core; - /// + /// /// class MainClass /// { /// public static void Main(string[] args) @@ -31,12 +31,12 @@ namespace ICSharpCode.SharpZipLib.GZip /// } /// } /// } - /// } + /// } /// /// public class GZipOutputStream : DeflaterOutputStream { - enum OutputState + private enum OutputState { Header, Footer, @@ -45,14 +45,18 @@ enum OutputState }; #region Instance Fields + /// /// CRC-32 value for uncompressed data /// protected Crc32 crc = new Crc32(); - OutputState state_ = OutputState.Header; - #endregion + + private OutputState state_ = OutputState.Header; + + #endregion Instance Fields #region Constructors + /// /// Creates a GzipOutputStream with the default buffer size /// @@ -76,9 +80,11 @@ public GZipOutputStream(Stream baseOutputStream) public GZipOutputStream(Stream baseOutputStream, int size) : base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size) { } - #endregion + + #endregion Constructors #region Public API + /// /// Sets the active compression level (0-9). The new level will be activated /// immediately. @@ -104,9 +110,11 @@ public int GetLevel() { return deflater_.GetLevel(); } - #endregion + + #endregion Public API #region Stream overrides + /// /// Write given buffer to output updating crc /// @@ -115,11 +123,13 @@ public int GetLevel() /// Number of bytes to write public override void Write(byte[] buffer, int offset, int count) { - if (state_ == OutputState.Header) { + if (state_ == OutputState.Header) + { WriteHeader(); } - if (state_ != OutputState.Footer) { + if (state_ != OutputState.Footer) + { throw new InvalidOperationException("Write not permitted in current state"); } @@ -133,31 +143,40 @@ public override void Write(byte[] buffer, int offset, int count) /// protected override void Dispose(bool disposing) { - try { + try + { Finish(); - } finally { - if (state_ != OutputState.Closed) { + } + finally + { + if (state_ != OutputState.Closed) + { state_ = OutputState.Closed; - if (IsStreamOwner) { + if (IsStreamOwner) + { baseOutputStream_.Dispose(); } } } } - #endregion + + #endregion Stream overrides #region DeflaterOutputStream overrides + /// /// Finish compression and write any footer information required to stream /// public override void Finish() { // If no data has been written a header should be added. - if (state_ == OutputState.Header) { + if (state_ == OutputState.Header) + { WriteHeader(); } - if (state_ == OutputState.Footer) { + if (state_ == OutputState.Footer) + { state_ = OutputState.Finished; base.Finish(); @@ -166,7 +185,8 @@ public override void Finish() byte[] gzipFooter; - unchecked { + unchecked + { gzipFooter = new byte[] { (byte) crcval, (byte) (crcval >> 8), (byte) (crcval >> 16), (byte) (crcval >> 24), @@ -179,12 +199,15 @@ public override void Finish() baseOutputStream_.Write(gzipFooter, 0, gzipFooter.Length); } } - #endregion + + #endregion DeflaterOutputStream overrides #region Support Routines - void WriteHeader() + + private void WriteHeader() { - if (state_ == OutputState.Header) { + if (state_ == OutputState.Header) + { state_ = OutputState.Footer; var mod_time = (int)((DateTime.Now.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000L); // Ticks give back 100ns intervals @@ -211,6 +234,7 @@ void WriteHeader() baseOutputStream_.Write(gzipHeader, 0, gzipHeader.Length); } } - #endregion + + #endregion Support Routines } } diff --git a/src/ICSharpCode.SharpZipLib/Lzw/LzwConstants.cs b/src/ICSharpCode.SharpZipLib/Lzw/LzwConstants.cs index d36eb362a..b7dc60f59 100644 --- a/src/ICSharpCode.SharpZipLib/Lzw/LzwConstants.cs +++ b/src/ICSharpCode.SharpZipLib/Lzw/LzwConstants.cs @@ -31,6 +31,7 @@ sealed public class LzwConstants /// Indicates the presence of a fourth header byte /// public const int EXTENDED_MASK = 0x20; + //public const int FREE_MASK = 0x40; /// @@ -54,7 +55,7 @@ sealed public class LzwConstants /// public const int INIT_BITS = 9; - LzwConstants() + private LzwConstants() { } } diff --git a/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs b/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs index 49374ec65..fc2a65aaa 100644 --- a/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs @@ -10,7 +10,7 @@ namespace ICSharpCode.SharpZipLib.Lzw /// /// See http://en.wikipedia.org/wiki/Compress /// See http://wiki.wxwidgets.org/Development:_Z_File_Format - /// + /// /// The file header consists of 3 (or optionally 4) bytes. The first two bytes /// contain the magic marker "0x1f 0x9d", followed by a byte of flags. /// @@ -21,10 +21,10 @@ namespace ICSharpCode.SharpZipLib.Lzw /// /// using System; /// using System.IO; - /// + /// /// using ICSharpCode.SharpZipLib.Core; /// using ICSharpCode.SharpZipLib.LZW; - /// + /// /// class MainClass /// { /// public static void Main(string[] args) @@ -38,7 +38,7 @@ namespace ICSharpCode.SharpZipLib.Lzw /// // now do something with the buffer /// } /// } - /// } + /// } /// /// public class LzwInputStream : Stream @@ -113,10 +113,10 @@ public override int Read(byte[] buffer, int offset, int count) byte[] lData = data; int lBitPos = bitPos; - // empty stack if stuff still left int sSize = lStack.Length - lStackP; - if (sSize > 0) { + if (sSize > 0) + { int num = (sSize >= count) ? count : sSize; Array.Copy(lStack, lStackP, buffer, offset, num); offset += num; @@ -124,26 +124,31 @@ public override int Read(byte[] buffer, int offset, int count) lStackP += num; } - if (count == 0) { + if (count == 0) + { stackP = lStackP; return offset - start; } - - // loop, filling local buffer until enough data has been decompressed - MainLoop: - do { - if (end < EXTRA) { + // loop, filling local buffer until enough data has been decompressed + MainLoop: + do + { + if (end < EXTRA) + { Fill(); } int bitIn = (got > 0) ? (end - end % lNBits) << 3 : (end << 3) - (lNBits - 1); - while (lBitPos < bitIn) { + while (lBitPos < bitIn) + { #region A + // handle 1-byte reads correctly - if (count == 0) { + if (count == 0) + { nBits = lNBits; maxCode = lMaxCode; maxMaxCode = lMaxMaxCode; @@ -158,7 +163,8 @@ public override int Read(byte[] buffer, int offset, int count) } // check for code-width expansion - if (lFreeEnt > lMaxCode) { + if (lFreeEnt > lMaxCode) + { int nBytes = lNBits << 3; lBitPos = (lBitPos - 1) + nBytes - (lBitPos - 1 + nBytes) % nBytes; @@ -171,9 +177,11 @@ public override int Read(byte[] buffer, int offset, int count) lBitPos = ResetBuf(lBitPos); goto MainLoop; } - #endregion + + #endregion A #region B + // read next code int pos = lBitPos >> 3; int code = (((lData[pos] & 0xFF) | @@ -184,7 +192,8 @@ public override int Read(byte[] buffer, int offset, int count) lBitPos += lNBits; // handle first iteration - if (lOldCode == -1) { + if (lOldCode == -1) + { if (code >= 256) throw new LzwException("corrupt input: " + code + " > 255"); @@ -195,7 +204,8 @@ public override int Read(byte[] buffer, int offset, int count) } // handle CLEAR code - if (code == TBL_CLEAR && blockMode) { + if (code == TBL_CLEAR && blockMode) + { Array.Copy(zeros, 0, lTabPrefix, 0, zeros.Length); lFreeEnt = TBL_FIRST - 1; @@ -210,16 +220,20 @@ public override int Read(byte[] buffer, int offset, int count) lBitPos = ResetBuf(lBitPos); goto MainLoop; } - #endregion + + #endregion B #region C + // setup int inCode = code; lStackP = lStack.Length; // Handle KwK case - if (code >= lFreeEnt) { - if (code > lFreeEnt) { + if (code >= lFreeEnt) + { + if (code > lFreeEnt) + { throw new LzwException("corrupt input: code=" + code + ", freeEnt=" + lFreeEnt); } @@ -229,7 +243,8 @@ public override int Read(byte[] buffer, int offset, int count) } // Generate output characters in reverse order - while (code >= 256) { + while (code >= 256) + { lStack[--lStackP] = lTabSuffix[code]; code = lTabPrefix[code]; } @@ -245,11 +260,14 @@ public override int Read(byte[] buffer, int offset, int count) offset += num; count -= num; lStackP += num; - #endregion + + #endregion C #region D + // generate new entry in table - if (lFreeEnt < lMaxMaxCode) { + if (lFreeEnt < lMaxMaxCode) + { lTabPrefix[lFreeEnt] = lOldCode; lTabSuffix[lFreeEnt] = lFinChar; lFreeEnt++; @@ -259,7 +277,8 @@ public override int Read(byte[] buffer, int offset, int count) lOldCode = inCode; // if output buffer full, then return - if (count == 0) { + if (count == 0) + { nBits = lNBits; maxCode = lMaxCode; bitMask = lBitMask; @@ -271,11 +290,11 @@ public override int Read(byte[] buffer, int offset, int count) return offset - start; } - #endregion + + #endregion D } // while lBitPos = ResetBuf(lBitPos); - } while (got > 0); // do..while nBits = lNBits; @@ -305,16 +324,15 @@ private int ResetBuf(int bitPosition) return 0; } - private void Fill() { got = baseInputStream.Read(data, end, data.Length - 1 - end); - if (got > 0) { + if (got > 0) + { end += got; } } - private void ParseHeader() { headerParsed = true; @@ -327,7 +345,8 @@ private void ParseHeader() if (result < 0) throw new LzwException("Failed to read LZW header"); - if (hdr[0] != (LzwConstants.MAGIC >> 8) || hdr[1] != (LzwConstants.MAGIC & 0xff)) { + if (hdr[0] != (LzwConstants.MAGIC >> 8) || hdr[1] != (LzwConstants.MAGIC & 0xff)) + { throw new LzwException(String.Format( "Wrong LZW header. Magic bytes don't match. 0x{0:x2} 0x{1:x2}", hdr[0], hdr[1])); @@ -337,13 +356,15 @@ private void ParseHeader() blockMode = (hdr[2] & LzwConstants.BLOCK_MODE_MASK) > 0; maxBits = hdr[2] & LzwConstants.BIT_MASK; - if (maxBits > LzwConstants.MAX_BITS) { + if (maxBits > LzwConstants.MAX_BITS) + { throw new LzwException("Stream compressed with " + maxBits + " bits, but decompression can only handle " + LzwConstants.MAX_BITS + " bits."); } - if ((hdr[2] & LzwConstants.RESERVED_MASK) > 0) { + if ((hdr[2] & LzwConstants.RESERVED_MASK) > 0) + { throw new LzwException("Unsupported bits set in the header."); } @@ -366,11 +387,14 @@ private void ParseHeader() } #region Stream Overrides + /// /// Gets a value indicating whether the current stream supports reading /// - public override bool CanRead { - get { + public override bool CanRead + { + get + { return baseInputStream.CanRead; } } @@ -378,8 +402,10 @@ public override bool CanRead { /// /// Gets a value of false indicating seeking is not supported for this stream. /// - public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return false; } } @@ -387,8 +413,10 @@ public override bool CanSeek { /// /// Gets a value of false indicating that this stream is not writeable. /// - public override bool CanWrite { - get { + public override bool CanWrite + { + get + { return false; } } @@ -396,8 +424,10 @@ public override bool CanWrite { /// /// A value representing the length of the stream in bytes. /// - public override long Length { - get { + public override long Length + { + get + { return got; } } @@ -407,11 +437,14 @@ public override long Length { /// Throws a NotSupportedException when attempting to set the position /// /// Attempting to set the position - public override long Position { - get { + public override long Position + { + get + { return baseInputStream.Position; } - set { + set + { throw new NotSupportedException("InflaterInputStream Position not supported"); } } @@ -478,30 +511,33 @@ public override void WriteByte(byte value) /// protected override void Dispose(bool disposing) { - if (!isClosed) { + if (!isClosed) + { isClosed = true; - if (IsStreamOwner) { + if (IsStreamOwner) + { baseInputStream.Dispose(); } } } - #endregion + #endregion Stream Overrides #region Instance Fields - Stream baseInputStream; + private Stream baseInputStream; /// /// Flag indicating wether this instance has been closed or not. /// - bool isClosed; + private bool isClosed; - readonly byte[] one = new byte[1]; - bool headerParsed; + private readonly byte[] one = new byte[1]; + private bool headerParsed; // string table stuff private const int TBL_CLEAR = 0x100; + private const int TBL_FIRST = TBL_CLEAR + 1; private int[] tabPrefix; @@ -511,6 +547,7 @@ protected override void Dispose(bool disposing) // various state private bool blockMode; + private int nBits; private int maxBits; private int maxMaxCode; @@ -523,11 +560,13 @@ protected override void Dispose(bool disposing) // input buffer private readonly byte[] data = new byte[1024 * 8]; + private int bitPos; private int end; - int got; + private int got; private bool eof; private const int EXTRA = 64; - #endregion + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs index 494425a65..34aaf65c4 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs @@ -19,12 +19,12 @@ namespace ICSharpCode.SharpZipLib.Tar /// header followed by the number of blocks needed to /// contain the file's contents. All entries are written on /// block boundaries. Blocks are 512 bytes long. - /// + /// /// TarArchives are instantiated in either read or write mode, /// based upon whether they are instantiated with an InputStream /// or an OutputStream. Once instantiated TarArchives read/write /// mode can not be changed. - /// + /// /// There is currently no support for random access to tar archives. /// However, it seems that subclassing TarArchive, and using the /// TarBuffer.CurrentRecord and TarBuffer.CurrentBlock @@ -45,12 +45,14 @@ public class TarArchive : IDisposable protected virtual void OnProgressMessageEvent(TarEntry entry, string message) { ProgressMessageHandler handler = ProgressMessageEvent; - if (handler != null) { + if (handler != null) + { handler(this, entry, message); } } #region Constructors + /// /// Constructor for a default . /// @@ -64,7 +66,8 @@ protected TarArchive() /// The to use for input. protected TarArchive(TarInputStream stream) { - if (stream == null) { + if (stream == null) + { throw new ArgumentNullException(nameof(stream)); } @@ -74,18 +77,21 @@ protected TarArchive(TarInputStream stream) /// /// Initialise a TarArchive for output. /// - /// The to use for output. + /// The to use for output. protected TarArchive(TarOutputStream stream) { - if (stream == null) { + if (stream == null) + { throw new ArgumentNullException(nameof(stream)); } tarOut = stream; } - #endregion + + #endregion Constructors #region Static factory methods + /// /// The InputStream based constructors create a TarArchive for the /// purposes of extracting or listing a tar archive. Thus, use @@ -96,16 +102,20 @@ protected TarArchive(TarOutputStream stream) /// Returns a new suitable for reading from. public static TarArchive CreateInputTarArchive(Stream inputStream) { - if (inputStream == null) { + if (inputStream == null) + { throw new ArgumentNullException(nameof(inputStream)); } var tarStream = inputStream as TarInputStream; TarArchive result; - if (tarStream != null) { + if (tarStream != null) + { result = new TarArchive(tarStream); - } else { + } + else + { result = CreateInputTarArchive(inputStream, TarBuffer.DefaultBlockFactor); } return result; @@ -119,11 +129,13 @@ public static TarArchive CreateInputTarArchive(Stream inputStream) /// Returns a suitable for reading. public static TarArchive CreateInputTarArchive(Stream inputStream, int blockFactor) { - if (inputStream == null) { + if (inputStream == null) + { throw new ArgumentNullException(nameof(inputStream)); } - if (inputStream is TarInputStream) { + if (inputStream is TarInputStream) + { throw new ArgumentException("TarInputStream not valid"); } @@ -137,16 +149,20 @@ public static TarArchive CreateInputTarArchive(Stream inputStream, int blockFact /// Returns a suitable for writing. public static TarArchive CreateOutputTarArchive(Stream outputStream) { - if (outputStream == null) { + if (outputStream == null) + { throw new ArgumentNullException(nameof(outputStream)); } var tarStream = outputStream as TarOutputStream; TarArchive result; - if (tarStream != null) { + if (tarStream != null) + { result = new TarArchive(tarStream); - } else { + } + else + { result = CreateOutputTarArchive(outputStream, TarBuffer.DefaultBlockFactor); } return result; @@ -160,17 +176,20 @@ public static TarArchive CreateOutputTarArchive(Stream outputStream) /// Returns a suitable for writing. public static TarArchive CreateOutputTarArchive(Stream outputStream, int blockFactor) { - if (outputStream == null) { + if (outputStream == null) + { throw new ArgumentNullException(nameof(outputStream)); } - if (outputStream is TarOutputStream) { + if (outputStream is TarOutputStream) + { throw new ArgumentException("TarOutputStream is not valid"); } return new TarArchive(new TarOutputStream(outputStream, blockFactor)); } - #endregion + + #endregion Static factory methods /// /// Set the flag that determines whether existing files are @@ -181,7 +200,8 @@ public static TarArchive CreateOutputTarArchive(Stream outputStream, int blockFa /// public void SetKeepOldFiles(bool keepExistingFiles) { - if (isDisposed) { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -190,30 +210,34 @@ public void SetKeepOldFiles(bool keepExistingFiles) /// /// Get/set the ascii file translation flag. If ascii file translation - /// is true, then the file is checked to see if it a binary file or not. - /// If the flag is true and the test indicates it is ascii text + /// is true, then the file is checked to see if it a binary file or not. + /// If the flag is true and the test indicates it is ascii text /// file, it will be translated. The translation converts the local /// operating system's concept of line ends into the UNIX line end, /// '\n', which is the defacto standard for a TAR archive. This makes /// text files compatible with UNIX. /// - public bool AsciiTranslate { - get { - if (isDisposed) { + public bool AsciiTranslate + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } return asciiTranslate; } - set { - if (isDisposed) { + set + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } asciiTranslate = value; } - } /// @@ -225,7 +249,8 @@ public bool AsciiTranslate { [Obsolete("Use the AsciiTranslate property")] public void SetAsciiTranslation(bool translateAsciiFiles) { - if (isDisposed) { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -234,42 +259,51 @@ public void SetAsciiTranslation(bool translateAsciiFiles) /// /// PathPrefix is added to entry names as they are written if the value is not null. - /// A slash character is appended after PathPrefix + /// A slash character is appended after PathPrefix /// - public string PathPrefix { - get { - if (isDisposed) { + public string PathPrefix + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } return pathPrefix; } - set { - if (isDisposed) { + set + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } pathPrefix = value; } - } /// /// RootPath is removed from entry names if it is found at the /// beginning of the name. /// - public string RootPath { - get { - if (isDisposed) { + public string RootPath + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } return rootPath; } - set { - if (isDisposed) { + set + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } // Convert to forward slashes for matching. Trim trailing / for correct final path @@ -279,7 +313,7 @@ public string RootPath { /// /// Set user and group information that will be used to fill in the - /// tar archive's entry headers. This information is based on that available + /// tar archive's entry headers. This information is based on that available /// for the linux operating system, which is not always available on other /// operating systems. TarArchive allows the programmer to specify values /// to be used in their place. @@ -299,7 +333,8 @@ public string RootPath { /// public void SetUserInfo(int userId, string userName, int groupId, string groupName) { - if (isDisposed) { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -314,17 +349,22 @@ public void SetUserInfo(int userId, string userName, int groupId, string groupNa /// Get or set a value indicating if overrides defined by SetUserInfo should be applied. /// /// If overrides are not applied then the values as set in each header will be used. - public bool ApplyUserInfoOverrides { - get { - if (isDisposed) { + public bool ApplyUserInfoOverrides + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } return applyUserInfoOverrides; } - set { - if (isDisposed) { + set + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -340,9 +380,12 @@ public bool ApplyUserInfoOverrides { /// /// The current user id. /// - public int UserId { - get { - if (isDisposed) { + public int UserId + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -358,9 +401,12 @@ public int UserId { /// /// The current user name. /// - public string UserName { - get { - if (isDisposed) { + public string UserName + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -376,9 +422,12 @@ public string UserName { /// /// The current group id. /// - public int GroupId { - get { - if (isDisposed) { + public int GroupId + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -394,9 +443,12 @@ public int GroupId { /// /// The current group name. /// - public string GroupName { - get { - if (isDisposed) { + public string GroupName + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } @@ -414,15 +466,21 @@ public string GroupName { /// /// The record size this archive is using. /// - public int RecordSize { - get { - if (isDisposed) { + public int RecordSize + { + get + { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } - if (tarIn != null) { + if (tarIn != null) + { return tarIn.RecordSize; - } else if (tarOut != null) { + } + else if (tarOut != null) + { return tarOut.RecordSize; } return TarBuffer.DefaultRecordSize; @@ -433,11 +491,16 @@ public int RecordSize { /// Sets the IsStreamOwner property on the underlying stream. /// Set this to false to prevent the Close of the TarArchive from closing the stream. /// - public bool IsStreamOwner { - set { - if (tarIn != null) { + public bool IsStreamOwner + { + set + { + if (tarIn != null) + { tarIn.IsStreamOwner = value; - } else { + } + else + { tarOut.IsStreamOwner = value; } } @@ -454,20 +517,23 @@ public void CloseArchive() /// /// Perform the "list" command for the archive contents. - /// + /// /// NOTE That this method uses the progress event to actually list /// the contents. If the progress display event is not set, nothing will be listed! /// public void ListContents() { - if (isDisposed) { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } - while (true) { + while (true) + { TarEntry entry = tarIn.GetNextEntry(); - if (entry == null) { + if (entry == null) + { break; } OnProgressMessageEvent(entry, null); @@ -482,14 +548,17 @@ public void ListContents() /// public void ExtractContents(string destinationDirectory) { - if (isDisposed) { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } - while (true) { + while (true) + { TarEntry entry = tarIn.GetNextEntry(); - if (entry == null) { + if (entry == null) + { break; } @@ -510,13 +579,14 @@ public void ExtractContents(string destinationDirectory) /// /// The TarEntry returned by tarIn.GetNextEntry(). /// - void ExtractEntry(string destDir, TarEntry entry) + private void ExtractEntry(string destDir, TarEntry entry) { OnProgressMessageEvent(entry, null); string name = entry.Name; - if (Path.IsPathRooted(name)) { + if (Path.IsPathRooted(name)) + { // NOTE: // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt name = name.Substring(Path.GetPathRoot(name).Length); @@ -526,62 +596,82 @@ void ExtractEntry(string destDir, TarEntry entry) string destFile = Path.Combine(destDir, name); - if (entry.IsDirectory) { + if (entry.IsDirectory) + { EnsureDirectoryExists(destFile); - } else { + } + else + { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); bool process = true; var fileInfo = new FileInfo(destFile); - if (fileInfo.Exists) { - if (keepOldFiles) { + if (fileInfo.Exists) + { + if (keepOldFiles) + { OnProgressMessageEvent(entry, "Destination file already exists"); process = false; - } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) { + } + else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) + { OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); process = false; } } - if (process) { + if (process) + { bool asciiTrans = false; Stream outputStream = File.Create(destFile); - if (this.asciiTranslate) { + if (this.asciiTranslate) + { asciiTrans = !IsBinary(destFile); } StreamWriter outw = null; - if (asciiTrans) { + if (asciiTrans) + { outw = new StreamWriter(outputStream); } byte[] rdbuf = new byte[32 * 1024]; - while (true) { + while (true) + { int numRead = tarIn.Read(rdbuf, 0, rdbuf.Length); - if (numRead <= 0) { + if (numRead <= 0) + { break; } - if (asciiTrans) { - for (int off = 0, b = 0; b < numRead; ++b) { - if (rdbuf[b] == 10) { + if (asciiTrans) + { + for (int off = 0, b = 0; b < numRead; ++b) + { + if (rdbuf[b] == 10) + { string s = Encoding.ASCII.GetString(rdbuf, off, (b - off)); outw.WriteLine(s); off = b + 1; } } - } else { + } + else + { outputStream.Write(rdbuf, 0, numRead); } } - if (asciiTrans) { + if (asciiTrans) + { outw.Dispose(); - } else { + } + else + { outputStream.Dispose(); } } @@ -603,22 +693,29 @@ void ExtractEntry(string destDir, TarEntry entry) /// public void WriteEntry(TarEntry sourceEntry, bool recurse) { - if (sourceEntry == null) { + if (sourceEntry == null) + { throw new ArgumentNullException(nameof(sourceEntry)); } - if (isDisposed) { + if (isDisposed) + { throw new ObjectDisposedException("TarArchive"); } - try { - if (recurse) { + try + { + if (recurse) + { TarHeader.SetValueDefaults(sourceEntry.UserId, sourceEntry.UserName, sourceEntry.GroupId, sourceEntry.GroupName); } WriteEntryCore(sourceEntry, recurse); - } finally { - if (recurse) { + } + finally + { + if (recurse) + { TarHeader.RestoreSetValues(); } } @@ -637,14 +734,15 @@ public void WriteEntry(TarEntry sourceEntry, bool recurse) /// /// If true, process the children of directory entries. /// - void WriteEntryCore(TarEntry sourceEntry, bool recurse) + private void WriteEntryCore(TarEntry sourceEntry, bool recurse) { string tempFileName = null; string entryFilename = sourceEntry.File; var entry = (TarEntry)sourceEntry.Clone(); - if (applyUserInfoOverrides) { + if (applyUserInfoOverrides) + { entry.GroupId = groupId; entry.GroupName = groupName; entry.UserId = userId; @@ -653,17 +751,21 @@ void WriteEntryCore(TarEntry sourceEntry, bool recurse) OnProgressMessageEvent(entry, null); - if (asciiTranslate && !entry.IsDirectory) { - - if (!IsBinary(entryFilename)) { + if (asciiTranslate && !entry.IsDirectory) + { + if (!IsBinary(entryFilename)) + { tempFileName = Path.GetTempFileName(); - using (StreamReader inStream = File.OpenText(entryFilename)) { - using (Stream outStream = File.Create(tempFileName)) { - - while (true) { + using (StreamReader inStream = File.OpenText(entryFilename)) + { + using (Stream outStream = File.Create(tempFileName)) + { + while (true) + { string line = inStream.ReadLine(); - if (line == null) { + if (line == null) + { break; } byte[] data = Encoding.ASCII.GetBytes(line); @@ -682,36 +784,48 @@ void WriteEntryCore(TarEntry sourceEntry, bool recurse) string newName = null; - if (rootPath != null) { - if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) { + if (rootPath != null) + { + if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) + { newName = entry.Name.Substring(rootPath.Length + 1); } } - if (pathPrefix != null) { + if (pathPrefix != null) + { newName = (newName == null) ? pathPrefix + "/" + entry.Name : pathPrefix + "/" + newName; } - if (newName != null) { + if (newName != null) + { entry.Name = newName; } tarOut.PutNextEntry(entry); - if (entry.IsDirectory) { - if (recurse) { + if (entry.IsDirectory) + { + if (recurse) + { TarEntry[] list = entry.GetDirectoryEntries(); - for (int i = 0; i < list.Length; ++i) { + for (int i = 0; i < list.Length; ++i) + { WriteEntryCore(list[i], recurse); } } - } else { - using (Stream inputStream = File.OpenRead(entryFilename)) { + } + else + { + using (Stream inputStream = File.OpenRead(entryFilename)) + { byte[] localBuffer = new byte[32 * 1024]; - while (true) { + while (true) + { int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length); - if (numRead <= 0) { + if (numRead <= 0) + { break; } @@ -719,7 +833,8 @@ void WriteEntryCore(TarEntry sourceEntry, bool recurse) } } - if (!string.IsNullOrEmpty(tempFileName)) { + if (!string.IsNullOrEmpty(tempFileName)) + { File.Delete(tempFileName); } @@ -743,15 +858,19 @@ public void Dispose() /// false to release only unmanaged resources. protected virtual void Dispose(bool disposing) { - if (!isDisposed) { + if (!isDisposed) + { isDisposed = true; - if (disposing) { - if (tarOut != null) { + if (disposing) + { + if (tarOut != null) + { tarOut.Flush(); tarOut.Dispose(); } - if (tarIn != null) { + if (tarIn != null) + { tarIn.Dispose(); } } @@ -775,12 +894,16 @@ public virtual void Close() Dispose(false); } - static void EnsureDirectoryExists(string directoryName) + private static void EnsureDirectoryExists(string directoryName) { - if (!Directory.Exists(directoryName)) { - try { + if (!Directory.Exists(directoryName)) + { + try + { Directory.CreateDirectory(directoryName); - } catch (Exception e) { + } + catch (Exception e) + { throw new TarException("Exception creating directory '" + directoryName + "', " + e.Message, e); } } @@ -790,17 +913,20 @@ static void EnsureDirectoryExists(string directoryName) // It no longer reads entire files into memory but is still a weak test! // This assumes that byte values 0-7, 14-31 or 255 are binary // and that all non text files contain one of these values - static bool IsBinary(string filename) + private static bool IsBinary(string filename) { - using (FileStream fs = File.OpenRead(filename)) { + using (FileStream fs = File.OpenRead(filename)) + { int sampleSize = Math.Min(4096, (int)fs.Length); byte[] content = new byte[sampleSize]; int bytesRead = fs.Read(content, 0, sampleSize); - for (int i = 0; i < bytesRead; ++i) { + for (int i = 0; i < bytesRead; ++i) + { byte b = content[i]; - if ((b < 8) || ((b > 13) && (b < 32)) || (b == 255)) { + if ((b < 8) || ((b > 13) && (b < 32)) || (b == 255)) + { return true; } } @@ -809,22 +935,24 @@ static bool IsBinary(string filename) } #region Instance Fields - bool keepOldFiles; - bool asciiTranslate; - int userId; - string userName = string.Empty; - int groupId; - string groupName = string.Empty; + private bool keepOldFiles; + private bool asciiTranslate; + + private int userId; + private string userName = string.Empty; + private int groupId; + private string groupName = string.Empty; + + private string rootPath; + private string pathPrefix; - string rootPath; - string pathPrefix; + private bool applyUserInfoOverrides; - bool applyUserInfoOverrides; + private TarInputStream tarIn; + private TarOutputStream tarOut; + private bool isDisposed; - TarInputStream tarIn; - TarOutputStream tarOut; - bool isDisposed; - #endregion + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs b/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs index 3e399a347..43a6d5cdf 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs @@ -17,7 +17,6 @@ namespace ICSharpCode.SharpZipLib.Tar /// public class TarBuffer { - /* A quote from GNU tar man file on blocking and records A `tar' archive file contains a series of blocks. Each block contains `BLOCKSIZE' bytes. Although this format may be thought of as @@ -41,6 +40,7 @@ or which contains garbage records after a zero block. */ #region Constants + /// /// The size of a block in a tar archive in bytes. /// @@ -62,15 +62,18 @@ or which contains garbage records after a zero block. /// The default size is 10KB. /// public const int DefaultRecordSize = BlockSize * DefaultBlockFactor; - #endregion + + #endregion Constants /// /// Get the record size for this buffer /// /// The record size in bytes. /// This is equal to the multiplied by the - public int RecordSize { - get { + public int RecordSize + { + get + { return recordSize; } } @@ -90,8 +93,10 @@ public int GetRecordSize() /// Get the Blocking factor for the buffer /// /// This is the number of blocks in each record. - public int BlockFactor { - get { + public int BlockFactor + { + get + { return blockFactor; } } @@ -120,7 +125,8 @@ protected TarBuffer() /// A new suitable for input. public static TarBuffer CreateInputTarBuffer(Stream inputStream) { - if (inputStream == null) { + if (inputStream == null) + { throw new ArgumentNullException(nameof(inputStream)); } @@ -135,11 +141,13 @@ public static TarBuffer CreateInputTarBuffer(Stream inputStream) /// A new suitable for input. public static TarBuffer CreateInputTarBuffer(Stream inputStream, int blockFactor) { - if (inputStream == null) { + if (inputStream == null) + { throw new ArgumentNullException(nameof(inputStream)); } - if (blockFactor <= 0) { + if (blockFactor <= 0) + { throw new ArgumentOutOfRangeException(nameof(blockFactor), "Factor cannot be negative"); } @@ -158,7 +166,8 @@ public static TarBuffer CreateInputTarBuffer(Stream inputStream, int blockFactor /// A new suitable for output. public static TarBuffer CreateOutputTarBuffer(Stream outputStream) { - if (outputStream == null) { + if (outputStream == null) + { throw new ArgumentNullException(nameof(outputStream)); } @@ -173,11 +182,13 @@ public static TarBuffer CreateOutputTarBuffer(Stream outputStream) /// A new suitable for output. public static TarBuffer CreateOutputTarBuffer(Stream outputStream, int blockFactor) { - if (outputStream == null) { + if (outputStream == null) + { throw new ArgumentNullException(nameof(outputStream)); } - if (blockFactor <= 0) { + if (blockFactor <= 0) + { throw new ArgumentOutOfRangeException(nameof(blockFactor), "Factor cannot be negative"); } @@ -192,16 +203,19 @@ public static TarBuffer CreateOutputTarBuffer(Stream outputStream, int blockFact /// /// Initialization common to all constructors. /// - void Initialize(int archiveBlockFactor) + private void Initialize(int archiveBlockFactor) { blockFactor = archiveBlockFactor; recordSize = archiveBlockFactor * BlockSize; recordBuffer = new byte[RecordSize]; - if (inputStream != null) { + if (inputStream != null) + { currentRecordIndex = -1; currentBlockIndex = BlockFactor; - } else { + } + else + { currentRecordIndex = 0; currentBlockIndex = 0; } @@ -219,16 +233,20 @@ void Initialize(int archiveBlockFactor) [Obsolete("Use IsEndOfArchiveBlock instead")] public bool IsEOFBlock(byte[] block) { - if (block == null) { + if (block == null) + { throw new ArgumentNullException(nameof(block)); } - if (block.Length != BlockSize) { + if (block.Length != BlockSize) + { throw new ArgumentException("block length is invalid"); } - for (int i = 0; i < BlockSize; ++i) { - if (block[i] != 0) { + for (int i = 0; i < BlockSize; ++i) + { + if (block[i] != 0) + { return false; } } @@ -236,7 +254,6 @@ public bool IsEOFBlock(byte[] block) return true; } - /// /// Determine if an archive block indicates the End of an Archive has been reached. /// End of archive is indicated by a block that consists entirely of null bytes. @@ -248,16 +265,20 @@ public bool IsEOFBlock(byte[] block) /// Returns true if the block is an EOF block; false otherwise. public static bool IsEndOfArchiveBlock(byte[] block) { - if (block == null) { + if (block == null) + { throw new ArgumentNullException(nameof(block)); } - if (block.Length != BlockSize) { + if (block.Length != BlockSize) + { throw new ArgumentException("block length is invalid"); } - for (int i = 0; i < BlockSize; ++i) { - if (block[i] != 0) { + for (int i = 0; i < BlockSize; ++i) + { + if (block[i] != 0) + { return false; } } @@ -270,12 +291,15 @@ public static bool IsEndOfArchiveBlock(byte[] block) /// public void SkipBlock() { - if (inputStream == null) { + if (inputStream == null) + { throw new TarException("no input stream defined"); } - if (currentBlockIndex >= BlockFactor) { - if (!ReadRecord()) { + if (currentBlockIndex >= BlockFactor) + { + if (!ReadRecord()) + { throw new TarException("Failed to read a record"); } } @@ -291,12 +315,15 @@ public void SkipBlock() /// public byte[] ReadBlock() { - if (inputStream == null) { + if (inputStream == null) + { throw new TarException("TarBuffer.ReadBlock - no input stream defined"); } - if (currentBlockIndex >= BlockFactor) { - if (!ReadRecord()) { + if (currentBlockIndex >= BlockFactor) + { + if (!ReadRecord()) + { throw new TarException("Failed to read a record"); } } @@ -314,9 +341,10 @@ public byte[] ReadBlock() /// /// false if End-Of-File, else true. /// - bool ReadRecord() + private bool ReadRecord() { - if (inputStream == null) { + if (inputStream == null) + { throw new TarException("no input stream stream defined"); } @@ -325,7 +353,8 @@ bool ReadRecord() int offset = 0; int bytesNeeded = RecordSize; - while (bytesNeeded > 0) { + while (bytesNeeded > 0) + { long numBytes = inputStream.Read(recordBuffer, offset, bytesNeeded); // @@ -341,7 +370,8 @@ bool ReadRecord() // // Thanks to 'Yohann.Roussel@alcatel.fr' for this fix. // - if (numBytes <= 0) { + if (numBytes <= 0) + { break; } @@ -358,7 +388,8 @@ bool ReadRecord() /// /// Block numbers are zero based values /// - public int CurrentBlock { + public int CurrentBlock + { get { return currentBlockIndex; } } @@ -390,7 +421,8 @@ public int GetCurrentBlockNum() /// /// The current zero based record number. /// - public int CurrentRecord { + public int CurrentRecord + { get { return currentRecordIndex; } } @@ -414,21 +446,25 @@ public int GetCurrentRecordNum() /// public void WriteBlock(byte[] block) { - if (block == null) { + if (block == null) + { throw new ArgumentNullException(nameof(block)); } - if (outputStream == null) { + if (outputStream == null) + { throw new TarException("TarBuffer.WriteBlock - no output stream defined"); } - if (block.Length != BlockSize) { + if (block.Length != BlockSize) + { string errorText = string.Format("TarBuffer.WriteBlock - block to write has length '{0}' which is not the block size of '{1}'", block.Length, BlockSize); throw new TarException(errorText); } - if (currentBlockIndex >= BlockFactor) { + if (currentBlockIndex >= BlockFactor) + { WriteRecord(); } @@ -449,25 +485,30 @@ public void WriteBlock(byte[] block) /// public void WriteBlock(byte[] buffer, int offset) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (outputStream == null) { + if (outputStream == null) + { throw new TarException("TarBuffer.WriteBlock - no output stream stream defined"); } - if ((offset < 0) || (offset >= buffer.Length)) { + if ((offset < 0) || (offset >= buffer.Length)) + { throw new ArgumentOutOfRangeException(nameof(offset)); } - if ((offset + BlockSize) > buffer.Length) { + if ((offset + BlockSize) > buffer.Length) + { string errorText = string.Format("TarBuffer.WriteBlock - record has length '{0}' with offset '{1}' which is less than the record size of '{2}'", buffer.Length, offset, recordSize); throw new TarException(errorText); } - if (currentBlockIndex >= BlockFactor) { + if (currentBlockIndex >= BlockFactor) + { WriteRecord(); } @@ -479,9 +520,10 @@ public void WriteBlock(byte[] buffer, int offset) /// /// Write a TarBuffer record to the archive. /// - void WriteRecord() + private void WriteRecord() { - if (outputStream == null) { + if (outputStream == null) + { throw new TarException("TarBuffer.WriteRecord no output stream defined"); } @@ -497,13 +539,15 @@ void WriteRecord() /// /// Any trailing bytes are set to zero which is by definition correct behaviour /// for the end of a tar stream. - void WriteFinalRecord() + private void WriteFinalRecord() { - if (outputStream == null) { + if (outputStream == null) + { throw new TarException("TarBuffer.WriteFinalRecord no output stream defined"); } - if (currentBlockIndex > 0) { + if (currentBlockIndex > 0) + { int dataBytes = currentBlockIndex * BlockSize; Array.Clear(recordBuffer, dataBytes, RecordSize - dataBytes); WriteRecord(); @@ -518,15 +562,20 @@ void WriteFinalRecord() /// public void Close() { - if (outputStream != null) { + if (outputStream != null) + { WriteFinalRecord(); - if (IsStreamOwner) { + if (IsStreamOwner) + { outputStream.Dispose(); } outputStream = null; - } else if (inputStream != null) { - if (IsStreamOwner) { + } + else if (inputStream != null) + { + if (IsStreamOwner) + { inputStream.Dispose(); } inputStream = null; @@ -534,15 +583,17 @@ public void Close() } #region Instance Fields - Stream inputStream; - Stream outputStream; - byte[] recordBuffer; - int currentBlockIndex; - int currentRecordIndex; + private Stream inputStream; + private Stream outputStream; + + private byte[] recordBuffer; + private int currentBlockIndex; + private int currentRecordIndex; + + private int recordSize = DefaultRecordSize; + private int blockFactor = DefaultBlockFactor; - int recordSize = DefaultRecordSize; - int blockFactor = DefaultBlockFactor; - #endregion + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs b/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs index 11f13c5d1..f7d2a493d 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs @@ -33,6 +33,7 @@ namespace ICSharpCode.SharpZipLib.Tar public class TarEntry { #region Constructors + /// /// Initialise a default instance of . /// @@ -60,15 +61,18 @@ public TarEntry(byte[] headerBuffer) /// Header details for entry public TarEntry(TarHeader header) { - if (header == null) { + if (header == null) + { throw new ArgumentNullException(nameof(header)); } this.header = (TarHeader)header.Clone(); } - #endregion + + #endregion Constructors #region ICloneable Members + /// /// Clone this tar entry. /// @@ -81,11 +85,12 @@ public object Clone() entry.Name = Name; return entry; } - #endregion + + #endregion ICloneable Members /// /// Construct an entry with only a name. - /// This allows the programmer to construct the entry's header "by hand". + /// This allows the programmer to construct the entry's header "by hand". /// /// The name to use for the entry /// Returns the newly created @@ -121,7 +126,8 @@ public override bool Equals(object obj) { var localEntry = obj as TarEntry; - if (localEntry != null) { + if (localEntry != null) + { return Name.Equals(localEntry.Name); } return false; @@ -149,7 +155,8 @@ public override int GetHashCode() /// public bool IsDescendent(TarEntry toTest) { - if (toTest == null) { + if (toTest == null) + { throw new ArgumentNullException(nameof(toTest)); } @@ -162,8 +169,10 @@ public bool IsDescendent(TarEntry toTest) /// /// This entry's TarHeader. /// - public TarHeader TarHeader { - get { + public TarHeader TarHeader + { + get + { return header; } } @@ -171,11 +180,14 @@ public TarHeader TarHeader { /// /// Get/Set this entry's name. /// - public string Name { - get { + public string Name + { + get + { return header.Name; } - set { + set + { header.Name = value; } } @@ -183,11 +195,14 @@ public string Name { /// /// Get/set this entry's user id. /// - public int UserId { - get { + public int UserId + { + get + { return header.UserId; } - set { + set + { header.UserId = value; } } @@ -195,11 +210,14 @@ public int UserId { /// /// Get/set this entry's group id. /// - public int GroupId { - get { + public int GroupId + { + get + { return header.GroupId; } - set { + set + { header.GroupId = value; } } @@ -207,11 +225,14 @@ public int GroupId { /// /// Get/set this entry's user name. /// - public string UserName { - get { + public string UserName + { + get + { return header.UserName; } - set { + set + { header.UserName = value; } } @@ -219,11 +240,14 @@ public string UserName { /// /// Get/set this entry's group name. /// - public string GroupName { - get { + public string GroupName + { + get + { return header.GroupName; } - set { + set + { header.GroupName = value; } } @@ -261,11 +285,14 @@ public void SetNames(string userName, string groupName) /// /// Get/Set the modification time for this entry /// - public DateTime ModTime { - get { + public DateTime ModTime + { + get + { return header.ModTime; } - set { + set + { header.ModTime = value; } } @@ -276,8 +303,10 @@ public DateTime ModTime { /// /// This entry's file. /// - public string File { - get { + public string File + { + get + { return file; } } @@ -285,11 +314,14 @@ public string File { /// /// Get/set this entry's recorded file size. /// - public long Size { - get { + public long Size + { + get + { return header.Size; } - set { + set + { header.Size = value; } } @@ -300,14 +332,19 @@ public long Size { /// /// True if this entry is a directory. /// - public bool IsDirectory { - get { - if (file != null) { + public bool IsDirectory + { + get + { + if (file != null) + { return Directory.Exists(file); } - if (header != null) { - if ((header.TypeFlag == TarHeader.LF_DIR) || Name.EndsWith("/", StringComparison.Ordinal)) { + if (header != null) + { + if ((header.TypeFlag == TarHeader.LF_DIR) || Name.EndsWith("/", StringComparison.Ordinal)) + { return true; } } @@ -326,11 +363,13 @@ public bool IsDirectory { /// public void GetFileTarHeader(TarHeader header, string file) { - if (header == null) { + if (header == null) + { throw new ArgumentNullException(nameof(header)); } - if (file == null) { + if (file == null) + { throw new ArgumentNullException(nameof(file)); } @@ -340,21 +379,22 @@ public void GetFileTarHeader(TarHeader header, string file) string name = file; // 23-Jan-2004 GnuTar allows device names in path where the name is not local to the current directory - if (name.IndexOf(Directory.GetCurrentDirectory(), StringComparison.Ordinal) == 0) { + if (name.IndexOf(Directory.GetCurrentDirectory(), StringComparison.Ordinal) == 0) + { name = name.Substring(Directory.GetCurrentDirectory().Length); } /* - if (Path.DirectorySeparatorChar == '\\') + if (Path.DirectorySeparatorChar == '\\') { // check if the OS is Windows // Strip off drive letters! - if (name.Length > 2) + if (name.Length > 2) { char ch1 = name[0]; char ch2 = name[1]; - if (ch2 == ':' && Char.IsLetter(ch1)) + if (ch2 == ':' && Char.IsLetter(ch1)) { name = name.Substring(2); } @@ -367,22 +407,27 @@ public void GetFileTarHeader(TarHeader header, string file) // No absolute pathnames // Windows (and Posix?) paths can start with UNC style "\\NetworkDrive\", // so we loop on starting /'s. - while (name.StartsWith("/", StringComparison.Ordinal)) { + while (name.StartsWith("/", StringComparison.Ordinal)) + { name = name.Substring(1); } header.LinkName = String.Empty; header.Name = name; - if (Directory.Exists(file)) { + if (Directory.Exists(file)) + { header.Mode = 1003; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_DIR; - if ((header.Name.Length == 0) || header.Name[header.Name.Length - 1] != '/') { + if ((header.Name.Length == 0) || header.Name[header.Name.Length - 1] != '/') + { header.Name = header.Name + "/"; } header.Size = 0; - } else { + } + else + { header.Mode = 33216; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_NORMAL; header.Size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; @@ -402,14 +447,16 @@ public void GetFileTarHeader(TarHeader header, string file) /// public TarEntry[] GetDirectoryEntries() { - if ((file == null) || !Directory.Exists(file)) { + if ((file == null) || !Directory.Exists(file)) + { return new TarEntry[0]; } string[] list = Directory.GetFileSystemEntries(file); TarEntry[] result = new TarEntry[list.Length]; - for (int i = 0; i < list.Length; ++i) { + for (int i = 0; i < list.Length; ++i) + { result[i] = TarEntry.CreateEntryFromFile(list[i]); } @@ -453,11 +500,13 @@ static public void AdjustEntryName(byte[] buffer, string newName) /// static public void NameTarHeader(TarHeader header, string name) { - if (header == null) { + if (header == null) + { throw new ArgumentNullException(nameof(header)); } - if (name == null) { + if (name == null) + { throw new ArgumentNullException(nameof(name)); } @@ -482,15 +531,17 @@ static public void NameTarHeader(TarHeader header, string name) } #region Instance Fields + /// /// The name of the file this entry represents or null if the entry is not based on a file. /// - string file; + private string file; /// /// The entry's header information. /// - TarHeader header; - #endregion + private TarHeader header; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarException.cs b/src/ICSharpCode.SharpZipLib/Tar/TarException.cs index 3970c5269..c24011c79 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarException.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarException.cs @@ -7,7 +7,6 @@ namespace ICSharpCode.SharpZipLib.Tar /// public class TarException : SharpZipBaseException { - /// /// Initialise a new instance of . /// diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs b/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs index e1ab189dc..d1d438ad0 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs @@ -1,22 +1,23 @@ -using System; -using System.Collections.Generic; -using System.IO; +using System.Collections.Generic; using System.Text; namespace ICSharpCode.SharpZipLib.Tar { + /// + /// Reads the extended header of a Tar stream + /// public class TarExtendedHeaderReader { - const byte LENGTH = 0; - const byte KEY = 1; - const byte VALUE = 2; - const byte END = 3; + private const byte LENGTH = 0; + private const byte KEY = 1; + private const byte VALUE = 2; + private const byte END = 3; private readonly Dictionary headers = new Dictionary(); private string[] headerParts = new string[3]; - int bbIndex; + private int bbIndex; private byte[] byteBuffer; private char[] charBuffer; @@ -27,11 +28,19 @@ public class TarExtendedHeaderReader private static readonly byte[] StateNext = new[] { (byte)' ', (byte)'=', (byte)'\n' }; + /// + /// Creates a new . + /// public TarExtendedHeaderReader() { ResetBuffers(); } + /// + /// Read bytes from + /// + /// + /// public void Read(byte[] buffer, int length) { for (int i = 0; i < length; i++) @@ -75,7 +84,9 @@ private void ResetBuffers() bbIndex = 0; } - + /// + /// Returns the parsed headers as key-value strings + /// public Dictionary Headers { get @@ -84,6 +95,5 @@ public Dictionary Headers return headers; } } - } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs b/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs index 6ce8c61f8..e29507427 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs @@ -17,7 +17,7 @@ namespace ICSharpCode.SharpZipLib.Tar /// /// This is the ustar (Posix 1003.1) header. /// - /// struct header + /// struct header /// { /// char t_name[100]; // 0 Filename /// char t_mode[8]; // 100 Permissions @@ -41,6 +41,7 @@ namespace ICSharpCode.SharpZipLib.Tar public class TarHeader { #region Constants + /// /// The length of the name field in a header buffer. /// @@ -234,9 +235,10 @@ public class TarHeader /// public const string GNU_TMAGIC = "ustar "; - const long timeConversionFactor = 10000000L; // 1 tick == 100 nanoseconds - readonly static DateTime dateTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0); - #endregion + private const long timeConversionFactor = 10000000L; // 1 tick == 100 nanoseconds + private static readonly DateTime dateTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0); + + #endregion Constants #region Constructors @@ -258,17 +260,21 @@ public TarHeader() Size = 0; } - #endregion + #endregion Constructors #region Properties + /// /// Get/set the name for this tar entry. /// /// Thrown when attempting to set the property to null. - public string Name { + public string Name + { get { return name; } - set { - if (value == null) { + set + { + if (value == null) + { throw new ArgumentNullException(nameof(value)); } name = value; @@ -288,12 +294,12 @@ public string GetName() /// /// Get/set the entry's Unix style permission mode. /// - public int Mode { + public int Mode + { get { return mode; } set { mode = value; } } - /// /// The entry's user id. /// @@ -301,12 +307,12 @@ public int Mode { /// This is only directly relevant to unix systems. /// The default is zero. /// - public int UserId { + public int UserId + { get { return userId; } set { userId = value; } } - /// /// Get/set the entry's group id. /// @@ -314,27 +320,29 @@ public int UserId { /// This is only directly relevant to linux/unix systems. /// The default value is zero. /// - public int GroupId { + public int GroupId + { get { return groupId; } set { groupId = value; } } - /// /// Get/set the entry's size. /// /// Thrown when setting the size to less than zero. - public long Size { + public long Size + { get { return size; } - set { - if (value < 0) { + set + { + if (value < 0) + { throw new ArgumentOutOfRangeException(nameof(value), "Cannot be less than zero"); } size = value; } } - /// /// Get/set the entry's modification time. /// @@ -342,101 +350,116 @@ public long Size { /// The modification time is only accurate to within a second. /// /// Thrown when setting the date time to less than 1/1/1970. - public DateTime ModTime { + public DateTime ModTime + { get { return modTime; } - set { - if (value < dateTime1970) { + set + { + if (value < dateTime1970) + { throw new ArgumentOutOfRangeException(nameof(value), "ModTime cannot be before Jan 1st 1970"); } modTime = new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second); } } - /// /// Get the entry's checksum. This is only valid/updated after writing or reading an entry. /// - public int Checksum { + public int Checksum + { get { return checksum; } } - /// /// Get value of true if the header checksum is valid, false otherwise. /// - public bool IsChecksumValid { + public bool IsChecksumValid + { get { return isChecksumValid; } } - /// /// Get/set the entry's type flag. /// - public byte TypeFlag { + public byte TypeFlag + { get { return typeFlag; } set { typeFlag = value; } } - /// /// The entry's link name. /// /// Thrown when attempting to set LinkName to null. - public string LinkName { + public string LinkName + { get { return linkName; } - set { - if (value == null) { + set + { + if (value == null) + { throw new ArgumentNullException(nameof(value)); } linkName = value; } } - /// /// Get/set the entry's magic tag. /// /// Thrown when attempting to set Magic to null. - public string Magic { + public string Magic + { get { return magic; } - set { - if (value == null) { + set + { + if (value == null) + { throw new ArgumentNullException(nameof(value)); } magic = value; } } - /// /// The entry's version. /// /// Thrown when attempting to set Version to null. - public string Version { - get { + public string Version + { + get + { return version; } - set { - if (value == null) { + set + { + if (value == null) + { throw new ArgumentNullException(nameof(value)); } version = value; } } - /// /// The entry's user name. /// - public string UserName { + public string UserName + { get { return userName; } - set { - if (value != null) { + set + { + if (value != null) + { userName = value.Substring(0, Math.Min(UNAMELEN, value.Length)); - } else { + } + else + { string currentUser = "user"; - if (currentUser.Length > UNAMELEN) { + if (currentUser.Length > UNAMELEN) + { currentUser = currentUser.Substring(0, UNAMELEN); } userName = currentUser; @@ -444,45 +467,50 @@ public string UserName { } } - /// /// Get/set the entry's group name. /// /// /// This is only directly relevant to unix systems. /// - public string GroupName { + public string GroupName + { get { return groupName; } - set { - if (value == null) { + set + { + if (value == null) + { groupName = "None"; - } else { + } + else + { groupName = value; } } } - /// /// Get/set the entry's major device number. /// - public int DevMajor { + public int DevMajor + { get { return devMajor; } set { devMajor = value; } } - /// /// Get/set the entry's minor device number. /// - public int DevMinor { + public int DevMinor + { get { return devMinor; } set { devMinor = value; } } - #endregion + #endregion Properties #region ICloneable Members + /// /// Create a new that is a copy of the current instance. /// @@ -491,7 +519,8 @@ public object Clone() { return this.MemberwiseClone(); } - #endregion + + #endregion ICloneable Members /// /// Parse TarHeader information from a header buffer. @@ -501,7 +530,8 @@ public object Clone() /// public void ParseBuffer(byte[] header) { - if (header == null) { + if (header == null) + { throw new ArgumentNullException(nameof(header)); } @@ -547,10 +577,10 @@ public void ParseBuffer(byte[] header) GroupName = ParseName(header, offset, GNAMELEN).ToString(); offset += GNAMELEN; - DevMajor = (int) ParseOctal(header, offset, DEVLEN); + DevMajor = (int)ParseOctal(header, offset, DEVLEN); offset += DEVLEN; - DevMinor = (int) ParseOctal(header, offset, DEVLEN); + DevMinor = (int)ParseOctal(header, offset, DEVLEN); offset += DEVLEN; string prefix = ParseName(header, offset, PREFIXLEN).ToString(); @@ -566,7 +596,8 @@ public void ParseBuffer(byte[] header) /// output buffer for header information public void WriteHeader(byte[] outBuffer) { - if (outBuffer == null) { + if (outBuffer == null) + { throw new ArgumentNullException(nameof(outBuffer)); } @@ -581,7 +612,8 @@ public void WriteHeader(byte[] outBuffer) offset = GetOctalBytes(GetCTime(ModTime), outBuffer, offset, MODTIMELEN); int csOffset = offset; - for (int c = 0; c < CHKSUMLEN; ++c) { + for (int c = 0; c < CHKSUMLEN; ++c) + { outBuffer[offset++] = (byte)' '; } @@ -593,12 +625,14 @@ public void WriteHeader(byte[] outBuffer) offset = GetNameBytes(UserName, outBuffer, offset, UNAMELEN); offset = GetNameBytes(GroupName, outBuffer, offset, GNAMELEN); - if ((TypeFlag == LF_CHR) || (TypeFlag == LF_BLK)) { + if ((TypeFlag == LF_CHR) || (TypeFlag == LF_BLK)) + { offset = GetOctalBytes(DevMajor, outBuffer, offset, DEVLEN); offset = GetOctalBytes(DevMinor, outBuffer, offset, DEVLEN); } - for (; offset < outBuffer.Length;) { + for (; offset < outBuffer.Length;) + { outBuffer[offset++] = 0; } @@ -627,7 +661,8 @@ public override bool Equals(object obj) var localHeader = obj as TarHeader; bool result; - if (localHeader != null) { + if (localHeader != null) + { result = (name == localHeader.name) && (mode == localHeader.mode) && (UserId == localHeader.UserId) @@ -643,7 +678,9 @@ public override bool Equals(object obj) && (GroupName == localHeader.GroupName) && (DevMajor == localHeader.DevMajor) && (DevMinor == localHeader.DevMinor); - } else { + } + else + { result = false; } return result; @@ -676,10 +713,12 @@ static internal void RestoreSetValues() // static private long ParseBinaryOrOctal(byte[] header, int offset, int length) { - if (header[offset] >= 0x80) { + if (header[offset] >= 0x80) + { // File sizes over 8GB are stored in 8 right-justified bytes of binary indicated by setting the high-order bit of the leftmost byte of a numeric field. long result = 0; - for (int pos = length - 8; pos < length; pos++) { + for (int pos = length - 8; pos < length; pos++) + { result = result << 8 | header[offset + pos]; } return result; @@ -696,7 +735,8 @@ static private long ParseBinaryOrOctal(byte[] header, int offset, int length) /// The long equivalent of the octal string. static public long ParseOctal(byte[] header, int offset, int length) { - if (header == null) { + if (header == null) + { throw new ArgumentNullException(nameof(header)); } @@ -704,17 +744,22 @@ static public long ParseOctal(byte[] header, int offset, int length) bool stillPadding = true; int end = offset + length; - for (int i = offset; i < end; ++i) { - if (header[i] == 0) { + for (int i = offset; i < end; ++i) + { + if (header[i] == 0) + { break; } - if (header[i] == (byte)' ' || header[i] == '0') { - if (stillPadding) { + if (header[i] == (byte)' ' || header[i] == '0') + { + if (stillPadding) + { continue; } - if (header[i] == (byte)' ') { + if (header[i] == (byte)' ') + { break; } } @@ -744,26 +789,32 @@ static public long ParseOctal(byte[] header, int offset, int length) /// static public StringBuilder ParseName(byte[] header, int offset, int length) { - if (header == null) { + if (header == null) + { throw new ArgumentNullException(nameof(header)); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset), "Cannot be less than zero"); } - if (length < 0) { + if (length < 0) + { throw new ArgumentOutOfRangeException(nameof(length), "Cannot be less than zero"); } - if (offset + length > header.Length) { + if (offset + length > header.Length) + { throw new ArgumentException("Exceeds header size", nameof(length)); } var result = new StringBuilder(length); - for (int i = offset; i < offset + length; ++i) { - if (header[i] == 0) { + for (int i = offset; i < offset + length; ++i) + { + if (header[i] == 0) + { break; } result.Append((char)header[i]); @@ -783,11 +834,13 @@ static public StringBuilder ParseName(byte[] header, int offset, int length) /// The next free index in the public static int GetNameBytes(StringBuilder name, int nameOffset, byte[] buffer, int bufferOffset, int length) { - if (name == null) { + if (name == null) + { throw new ArgumentNullException(nameof(name)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } @@ -805,21 +858,25 @@ public static int GetNameBytes(StringBuilder name, int nameOffset, byte[] buffer /// The next free index in the public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int bufferOffset, int length) { - if (name == null) { + if (name == null) + { throw new ArgumentNullException(nameof(name)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } int i; - - for (i = 0 ; i < length && nameOffset + i < name.Length; ++i) { + + for (i = 0; i < length && nameOffset + i < name.Length; ++i) + { buffer[bufferOffset + i] = (byte)name[nameOffset + i]; } - for (; i < length; ++i) { + for (; i < length; ++i) + { buffer[bufferOffset + i] = 0; } @@ -846,12 +903,13 @@ public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int b /// public static int GetNameBytes(StringBuilder name, byte[] buffer, int offset, int length) { - - if (name == null) { + if (name == null) + { throw new ArgumentNullException(nameof(name)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } @@ -868,12 +926,13 @@ public static int GetNameBytes(StringBuilder name, byte[] buffer, int offset, in /// The index of the next free byte in the buffer public static int GetNameBytes(string name, byte[] buffer, int offset, int length) { - - if (name == null) { + if (name == null) + { throw new ArgumentNullException(nameof(name)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } @@ -891,16 +950,19 @@ public static int GetNameBytes(string name, byte[] buffer, int offset, int lengt /// The next free index in the buffer. public static int GetAsciiBytes(string toAdd, int nameOffset, byte[] buffer, int bufferOffset, int length) { - if (toAdd == null) { + if (toAdd == null) + { throw new ArgumentNullException(nameof(toAdd)); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } int i; - for (i = 0; i < length && nameOffset + i < toAdd.Length; ++i) { + for (i = 0; i < length && nameOffset + i < toAdd.Length; ++i) + { buffer[bufferOffset + i] = (byte)toAdd[nameOffset + i]; } // If length is beyond the toAdd string length (which is OK by the prev loop condition), eg if a field has fixed length and the string is shorter, make sure all of the extra chars are written as NULLs, so that the reader func would ignore them and get back the original string @@ -929,7 +991,8 @@ public static int GetAsciiBytes(string toAdd, int nameOffset, byte[] buffer, int /// public static int GetOctalBytes(long value, byte[] buffer, int offset, int length) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } @@ -939,14 +1002,17 @@ public static int GetOctalBytes(long value, byte[] buffer, int offset, int lengt buffer[offset + localIndex] = 0; --localIndex; - if (value > 0) { - for (long v = value; (localIndex >= 0) && (v > 0); --localIndex) { + if (value > 0) + { + for (long v = value; (localIndex >= 0) && (v > 0); --localIndex) + { buffer[offset + localIndex] = (byte)((byte)'0' + (byte)(v & 7)); v >>= 3; } } - for (; localIndex >= 0; --localIndex) { + for (; localIndex >= 0; --localIndex) + { buffer[offset + localIndex] = (byte)'0'; } @@ -963,9 +1029,11 @@ public static int GetOctalBytes(long value, byte[] buffer, int offset, int lengt /// Index of next byte private static int GetBinaryOrOctalBytes(long value, byte[] buffer, int offset, int length) { - if (value > 0x1FFFFFFFF) { // Octal 77777777777 (11 digits) - // Put value as binary, right-justified into the buffer. Set high order bit of left-most byte. - for (int pos = length - 1; pos > 0; pos--) { + if (value > 0x1FFFFFFFF) + { // Octal 77777777777 (11 digits) + // Put value as binary, right-justified into the buffer. Set high order bit of left-most byte. + for (int pos = length - 1; pos > 0; pos--) + { buffer[offset + pos] = (byte)value; value = value >> 8; } @@ -987,21 +1055,22 @@ private static int GetBinaryOrOctalBytes(long value, byte[] buffer, int offset, /// The final space is already there, from checksumming /// /// The modified buffer offset - static void GetCheckSumOctalBytes(long value, byte[] buffer, int offset, int length) + private static void GetCheckSumOctalBytes(long value, byte[] buffer, int offset, int length) { GetOctalBytes(value, buffer, offset, length - 1); } /// - /// Compute the checksum for a tar entry header. + /// Compute the checksum for a tar entry header. /// The checksum field must be all spaces prior to this happening /// /// The tar entry's header buffer. /// The computed checksum. - static int ComputeCheckSum(byte[] buffer) + private static int ComputeCheckSum(byte[] buffer) { int sum = 0; - for (int i = 0; i < buffer.Length; ++i) { + for (int i = 0; i < buffer.Length; ++i) + { sum += buffer[i]; } return sum; @@ -1012,62 +1081,72 @@ static int ComputeCheckSum(byte[] buffer) /// /// The tar entry's header buffer. /// The checksum for the buffer - static int MakeCheckSum(byte[] buffer) + private static int MakeCheckSum(byte[] buffer) { int sum = 0; - for (int i = 0; i < CHKSUMOFS; ++i) { + for (int i = 0; i < CHKSUMOFS; ++i) + { sum += buffer[i]; } - for (int i = 0; i < CHKSUMLEN; ++i) { + for (int i = 0; i < CHKSUMLEN; ++i) + { sum += (byte)' '; } - for (int i = CHKSUMOFS + CHKSUMLEN; i < buffer.Length; ++i) { + for (int i = CHKSUMOFS + CHKSUMLEN; i < buffer.Length; ++i) + { sum += buffer[i]; } return sum; } - static int GetCTime(DateTime dateTime) + private static int GetCTime(DateTime dateTime) { return unchecked((int)((dateTime.Ticks - dateTime1970.Ticks) / timeConversionFactor)); } - static DateTime GetDateTimeFromCTime(long ticks) + private static DateTime GetDateTimeFromCTime(long ticks) { DateTime result; - try { + try + { result = new DateTime(dateTime1970.Ticks + ticks * timeConversionFactor); - } catch (ArgumentOutOfRangeException) { + } + catch (ArgumentOutOfRangeException) + { result = dateTime1970; } return result; } #region Instance Fields - string name; - int mode; - int userId; - int groupId; - long size; - DateTime modTime; - int checksum; - bool isChecksumValid; - byte typeFlag; - string linkName; - string magic; - string version; - string userName; - string groupName; - int devMajor; - int devMinor; - #endregion + + private string name; + private int mode; + private int userId; + private int groupId; + private long size; + private DateTime modTime; + private int checksum; + private bool isChecksumValid; + private byte typeFlag; + private string linkName; + private string magic; + private string version; + private string userName; + private string groupName; + private int devMajor; + private int devMinor; + + #endregion Instance Fields #region Class Fields + // Values used during recursive operations. static internal int userIdAsSet; + static internal int groupIdAsSet; static internal string userNameAsSet; static internal string groupNameAsSet = "None"; @@ -1076,6 +1155,7 @@ static DateTime GetDateTimeFromCTime(long ticks) static internal int defaultGroupId; static internal string defaultGroupName = "None"; static internal string defaultUser; - #endregion + + #endregion Class Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs b/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs index 94a475e9e..3c0cd96cd 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs @@ -13,6 +13,7 @@ namespace ICSharpCode.SharpZipLib.Tar public class TarInputStream : Stream { #region Constructors + /// /// Construct a TarInputStream with default block factor /// @@ -33,24 +34,28 @@ public TarInputStream(Stream inputStream, int blockFactor) tarBuffer = TarBuffer.CreateInputTarBuffer(inputStream, blockFactor); } - #endregion + #endregion Constructors /// /// Gets or sets a flag indicating ownership of underlying stream. /// When the flag is true will close the underlying stream also. /// /// The default value is true. - public bool IsStreamOwner { + public bool IsStreamOwner + { get { return tarBuffer.IsStreamOwner; } set { tarBuffer.IsStreamOwner = value; } } #region Stream Overrides + /// /// Gets a value indicating whether the current stream supports reading /// - public override bool CanRead { - get { + public override bool CanRead + { + get + { return inputStream.CanRead; } } @@ -59,8 +64,10 @@ public override bool CanRead { /// Gets a value indicating whether the current stream supports seeking /// This property always returns false. /// - public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return false; } } @@ -69,8 +76,10 @@ public override bool CanSeek { /// Gets a value indicating if the stream supports writing. /// This property always returns false. /// - public override bool CanWrite { - get { + public override bool CanWrite + { + get + { return false; } } @@ -78,22 +87,27 @@ public override bool CanWrite { /// /// The length in bytes of the stream /// - public override long Length { - get { + public override long Length + { + get + { return inputStream.Length; } } /// - /// Gets or sets the position within the stream. + /// Gets or sets the position within the stream. /// Setting the Position is not supported and throws a NotSupportedExceptionNotSupportedException /// /// Any attempt to set position - public override long Position { - get { + public override long Position + { + get + { return inputStream.Position; } - set { + set + { throw new NotSupportedException("TarInputStream Seek not supported"); } } @@ -152,6 +166,7 @@ public override void WriteByte(byte value) { throw new NotSupportedException("TarInputStream WriteByte not supported"); } + /// /// Reads a byte from the current tar archive entry. /// @@ -160,7 +175,8 @@ public override int ReadByte() { byte[] oneByteBuffer = new byte[1]; int num = Read(oneByteBuffer, 0, 1); - if (num <= 0) { + if (num <= 0) + { // return -1 to indicate that no byte was read. return -1; } @@ -169,7 +185,7 @@ public override int ReadByte() /// /// Reads bytes from the current tar archive entry. - /// + /// /// This method is aware of the boundaries of the current /// entry in the archive and will deal with them appropriately /// @@ -187,30 +203,37 @@ public override int ReadByte() /// public override int Read(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } int totalRead = 0; - if (entryOffset >= entrySize) { + if (entryOffset >= entrySize) + { return 0; } long numToRead = count; - if ((numToRead + entryOffset) > entrySize) { + if ((numToRead + entryOffset) > entrySize) + { numToRead = entrySize - entryOffset; } - if (readBuffer != null) { + if (readBuffer != null) + { int sz = (numToRead > readBuffer.Length) ? readBuffer.Length : (int)numToRead; Array.Copy(readBuffer, 0, buffer, offset, sz); - if (sz >= readBuffer.Length) { + if (sz >= readBuffer.Length) + { readBuffer = null; - } else { + } + else + { int newLen = readBuffer.Length - sz; byte[] newBuf = new byte[newLen]; Array.Copy(readBuffer, sz, newBuf, 0, newLen); @@ -222,9 +245,11 @@ public override int Read(byte[] buffer, int offset, int count) offset += sz; } - while (numToRead > 0) { + while (numToRead > 0) + { byte[] rec = tarBuffer.ReadBlock(); - if (rec == null) { + if (rec == null) + { // Unexpected EOF! throw new TarException("unexpected EOF with " + numToRead + " bytes unread"); } @@ -232,11 +257,14 @@ public override int Read(byte[] buffer, int offset, int count) var sz = (int)numToRead; int recLen = rec.Length; - if (recLen > sz) { + if (recLen > sz) + { Array.Copy(rec, 0, buffer, offset, sz); readBuffer = new byte[recLen - sz]; Array.Copy(rec, sz, readBuffer, 0, recLen - sz); - } else { + } + else + { sz = recLen; Array.Copy(rec, 0, buffer, offset, recLen); } @@ -263,7 +291,7 @@ protected override void Dispose(bool disposing) } } - #endregion + #endregion Stream Overrides /// /// Set the entry factory for this instance. @@ -277,7 +305,8 @@ public void SetEntryFactory(IEntryFactory factory) /// /// Get the record size being used by this stream's TarBuffer. /// - public int RecordSize { + public int RecordSize + { get { return tarBuffer.RecordSize; } } @@ -303,8 +332,10 @@ public int GetRecordSize() /// /// The number of available bytes for the current entry. /// - public long Available { - get { + public long Available + { + get + { return entrySize - entryOffset; } } @@ -326,11 +357,13 @@ public void Skip(long skipCount) // byte[] skipBuf = new byte[8 * 1024]; - for (long num = skipCount; num > 0;) { + for (long num = skipCount; num > 0;) + { int toRead = num > skipBuf.Length ? skipBuf.Length : (int)num; int numRead = Read(skipBuf, 0, toRead); - if (numRead == -1) { + if (numRead == -1) + { break; } @@ -342,8 +375,10 @@ public void Skip(long skipCount) /// Return a value of true if marking is supported; false otherwise. /// /// Currently marking is not supported, the return value is always false. - public bool IsMarkSupported { - get { + public bool IsMarkSupported + { + get + { return false; } } @@ -380,11 +415,13 @@ public void Reset() /// public TarEntry GetNextEntry() { - if (hasHitEOF) { + if (hasHitEOF) + { return null; } - if (currentEntry != null) { + if (currentEntry != null) + { SkipToNextEntry(); } @@ -406,13 +443,18 @@ public TarEntry GetNextEntry() hasHitEOF = false; } - if (hasHitEOF) { + if (hasHitEOF) + { currentEntry = null; - } else { - try { + } + else + { + try + { var header = new TarHeader(); header.ParseBuffer(headerBuf); - if (!header.IsChecksumValid) { + if (!header.IsChecksumValid) + { throw new TarException("Header checksum is invalid"); } this.entryOffset = 0; @@ -420,17 +462,19 @@ public TarEntry GetNextEntry() StringBuilder longName = null; - if (header.TypeFlag == TarHeader.LF_GNU_LONGNAME) { - + if (header.TypeFlag == TarHeader.LF_GNU_LONGNAME) + { byte[] nameBuffer = new byte[TarBuffer.BlockSize]; long numToRead = this.entrySize; longName = new StringBuilder(); - while (numToRead > 0) { + while (numToRead > 0) + { int numRead = this.Read(nameBuffer, 0, (numToRead > nameBuffer.Length ? nameBuffer.Length : (int)numToRead)); - if (numRead == -1) { + if (numRead == -1) + { throw new InvalidHeaderException("Failed to read long name entry"); } @@ -440,12 +484,15 @@ public TarEntry GetNextEntry() SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); - } else if (header.TypeFlag == TarHeader.LF_GHDR) { // POSIX global extended header - // Ignore things we dont understand completely for now + } + else if (header.TypeFlag == TarHeader.LF_GHDR) + { // POSIX global extended header + // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); - } else if (header.TypeFlag == TarHeader.LF_XHDR) { // POSIX extended header - + } + else if (header.TypeFlag == TarHeader.LF_XHDR) + { // POSIX extended header byte[] nameBuffer = new byte[TarBuffer.BlockSize]; long numToRead = this.entrySize; @@ -471,26 +518,34 @@ public TarEntry GetNextEntry() SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); - } else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR) { + } + else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR) + { // TODO: could show volume name when verbose SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); - } else if (header.TypeFlag != TarHeader.LF_NORMAL && - header.TypeFlag != TarHeader.LF_OLDNORM && - header.TypeFlag != TarHeader.LF_LINK && - header.TypeFlag != TarHeader.LF_SYMLINK && - header.TypeFlag != TarHeader.LF_DIR) { + } + else if (header.TypeFlag != TarHeader.LF_NORMAL && + header.TypeFlag != TarHeader.LF_OLDNORM && + header.TypeFlag != TarHeader.LF_LINK && + header.TypeFlag != TarHeader.LF_SYMLINK && + header.TypeFlag != TarHeader.LF_DIR) + { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = tarBuffer.ReadBlock(); } - if (entryFactory == null) { + if (entryFactory == null) + { currentEntry = new TarEntry(headerBuf); - if (longName != null) { + if (longName != null) + { currentEntry.Name = longName.ToString(); } - } else { + } + else + { currentEntry = entryFactory.CreateEntry(headerBuf); } @@ -501,7 +556,9 @@ public TarEntry GetNextEntry() // TODO: Review How do we resolve this discrepancy?! entrySize = this.currentEntry.Size; - } catch (InvalidHeaderException ex) { + } + catch (InvalidHeaderException ex) + { entrySize = 0; entryOffset = 0; currentEntry = null; @@ -524,20 +581,23 @@ public void CopyEntryContents(Stream outputStream) { byte[] tempBuffer = new byte[32 * 1024]; - while (true) { + while (true) + { int numRead = Read(tempBuffer, 0, tempBuffer.Length); - if (numRead <= 0) { + if (numRead <= 0) + { break; } outputStream.Write(tempBuffer, 0, numRead); } } - void SkipToNextEntry() + private void SkipToNextEntry() { long numToSkip = entrySize - entryOffset; - if (numToSkip > 0) { + if (numToSkip > 0) + { Skip(numToSkip); } @@ -610,7 +670,7 @@ public TarEntry CreateEntryFromFile(string fileName) /// /// Create an entry based on details in header - /// + /// /// The buffer containing entry details. /// A new public TarEntry CreateEntry(byte[] headerBuffer) @@ -620,6 +680,7 @@ public TarEntry CreateEntry(byte[] headerBuffer) } #region Instance Fields + /// /// Flag set when last block has been read /// @@ -637,7 +698,7 @@ public TarEntry CreateEntry(byte[] headerBuffer) /// /// Buffer used with calls to Read() - /// + /// protected byte[] readBuffer; /// @@ -648,7 +709,7 @@ public TarEntry CreateEntry(byte[] headerBuffer) /// /// Current entry being read /// - TarEntry currentEntry; + private TarEntry currentEntry; /// /// Factory used to create TarEntry or descendant class instance @@ -658,7 +719,8 @@ public TarEntry CreateEntry(byte[] headerBuffer) /// /// Stream used as the source of input data. /// - readonly Stream inputStream; - #endregion + private readonly Stream inputStream; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs b/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs index e47db23b0..09202caa7 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs @@ -12,6 +12,7 @@ namespace ICSharpCode.SharpZipLib.Tar public class TarOutputStream : Stream { #region Constructors + /// /// Construct TarOutputStream using default block factor /// @@ -28,7 +29,8 @@ public TarOutputStream(Stream outputStream) /// blocking factor public TarOutputStream(Stream outputStream, int blockFactor) { - if (outputStream == null) { + if (outputStream == null) + { throw new ArgumentNullException(nameof(outputStream)); } @@ -38,14 +40,16 @@ public TarOutputStream(Stream outputStream, int blockFactor) assemblyBuffer = new byte[TarBuffer.BlockSize]; blockBuffer = new byte[TarBuffer.BlockSize]; } - #endregion + + #endregion Constructors /// /// Gets or sets a flag indicating ownership of underlying stream. /// When the flag is true will close the underlying stream also. /// /// The default value is true. - public bool IsStreamOwner { + public bool IsStreamOwner + { get { return buffer.IsStreamOwner; } set { buffer.IsStreamOwner = value; } } @@ -53,8 +57,10 @@ public bool IsStreamOwner { /// /// true if the stream supports reading; otherwise, false. /// - public override bool CanRead { - get { + public override bool CanRead + { + get + { return outputStream.CanRead; } } @@ -62,8 +68,10 @@ public override bool CanRead { /// /// true if the stream supports seeking; otherwise, false. /// - public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return outputStream.CanSeek; } } @@ -71,8 +79,10 @@ public override bool CanSeek { /// /// true if stream supports writing; otherwise, false. /// - public override bool CanWrite { - get { + public override bool CanWrite + { + get + { return outputStream.CanWrite; } } @@ -80,8 +90,10 @@ public override bool CanWrite { /// /// length of stream in bytes /// - public override long Length { - get { + public override long Length + { + get + { return outputStream.Length; } } @@ -89,11 +101,14 @@ public override long Length { /// /// gets or sets the position within the current stream. /// - public override long Position { - get { + public override long Position + { + get + { return outputStream.Position; } - set { + set + { outputStream.Position = value; } } @@ -119,7 +134,7 @@ public override void SetLength(long value) } /// - /// Read a byte from the stream and advance the position within the stream + /// Read a byte from the stream and advance the position within the stream /// by one byte or returns -1 if at the end of the stream. /// /// The byte value or -1 if at end of stream @@ -129,7 +144,7 @@ public override int ReadByte() } /// - /// read bytes from the current stream and advance the position within the + /// read bytes from the current stream and advance the position within the /// stream by the number of bytes read. /// /// The buffer to store read bytes in. @@ -145,7 +160,7 @@ public override int Read(byte[] buffer, int offset, int count) /// /// All buffered data is written to destination - /// + /// public override void Flush() { outputStream.Flush(); @@ -157,7 +172,8 @@ public override void Flush() /// public void Finish() { - if (IsEntryOpen) { + if (IsEntryOpen) + { CloseEntry(); } WriteEofBlock(); @@ -170,7 +186,8 @@ public void Finish() /// TarBuffer's Close(). protected override void Dispose(bool disposing) { - if (!isClosed) { + if (!isClosed) + { isClosed = true; Finish(); buffer.Close(); @@ -180,7 +197,8 @@ protected override void Dispose(bool disposing) /// /// Get the record size being used by this stream's TarBuffer. /// - public int RecordSize { + public int RecordSize + { get { return buffer.RecordSize; } } @@ -199,9 +217,9 @@ public int GetRecordSize() /// /// Get a value indicating wether an entry is open, requiring more data to be written. /// - bool IsEntryOpen { + private bool IsEntryOpen + { get { return (currBytes < currSize); } - } /// @@ -218,11 +236,13 @@ bool IsEntryOpen { /// public void PutNextEntry(TarEntry entry) { - if (entry == null) { + if (entry == null) + { throw new ArgumentNullException(nameof(entry)); } - if (entry.TarHeader.Name.Length > TarHeader.NAMELEN) { + if (entry.TarHeader.Name.Length > TarHeader.NAMELEN) + { var longHeader = new TarHeader(); longHeader.TypeFlag = TarHeader.LF_GNU_LONGNAME; longHeader.Name = longHeader.Name + "././@LongLink"; @@ -239,7 +259,8 @@ public void PutNextEntry(TarEntry entry) int nameCharIndex = 0; - while (nameCharIndex < entry.TarHeader.Name.Length + 1 /* we've allocated one for the null char, now we must make sure it gets written out */) { + while (nameCharIndex < entry.TarHeader.Name.Length + 1 /* we've allocated one for the null char, now we must make sure it gets written out */) + { Array.Clear(blockBuffer, 0, blockBuffer.Length); TarHeader.GetAsciiBytes(entry.TarHeader.Name, nameCharIndex, this.blockBuffer, 0, TarBuffer.BlockSize); // This func handles OK the extra char out of string length nameCharIndex += TarBuffer.BlockSize; @@ -266,7 +287,8 @@ public void PutNextEntry(TarEntry entry) /// public void CloseEntry() { - if (assemblyBufferLength > 0) { + if (assemblyBufferLength > 0) + { Array.Clear(assemblyBuffer, assemblyBufferLength, assemblyBuffer.Length - assemblyBufferLength); buffer.WriteBlock(assemblyBuffer); @@ -275,7 +297,8 @@ public void CloseEntry() assemblyBufferLength = 0; } - if (currBytes < currSize) { + if (currBytes < currSize) + { string errorText = string.Format( "Entry closed at '{0}' before the '{1}' bytes specified in the header were written", currBytes, currSize); @@ -315,23 +338,28 @@ public override void WriteByte(byte value) /// public override void Write(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset), "Cannot be negative"); } - if (buffer.Length - offset < count) { + if (buffer.Length - offset < count) + { throw new ArgumentException("offset and count combination is invalid"); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count), "Cannot be negative"); } - if ((currBytes + count) > currSize) { + if ((currBytes + count) > currSize) + { string errorText = string.Format("request to write '{0}' bytes exceeds size in header of '{1}' bytes", count, this.currSize); throw new ArgumentOutOfRangeException(nameof(count), errorText); @@ -344,8 +372,10 @@ public override void Write(byte[] buffer, int offset, int count) // TODO REVIEW Maybe this should be in TarBuffer? Could that help to // eliminate some of the buffer copying. // - if (assemblyBufferLength > 0) { - if ((assemblyBufferLength + count) >= blockBuffer.Length) { + if (assemblyBufferLength > 0) + { + if ((assemblyBufferLength + count) >= blockBuffer.Length) + { int aLen = blockBuffer.Length - assemblyBufferLength; Array.Copy(assemblyBuffer, 0, blockBuffer, 0, assemblyBufferLength); @@ -359,7 +389,9 @@ public override void Write(byte[] buffer, int offset, int count) count -= aLen; assemblyBufferLength = 0; - } else { + } + else + { Array.Copy(buffer, offset, assemblyBuffer, assemblyBufferLength, count); offset += count; assemblyBufferLength += count; @@ -372,8 +404,10 @@ public override void Write(byte[] buffer, int offset, int count) // o An empty "assembly" buffer. // o No bytes to write (count == 0) // - while (count > 0) { - if (count < blockBuffer.Length) { + while (count > 0) + { + if (count < blockBuffer.Length) + { Array.Copy(buffer, offset, assemblyBuffer, assemblyBufferLength, count); assemblyBufferLength += count; break; @@ -392,7 +426,7 @@ public override void Write(byte[] buffer, int offset, int count) /// Write an EOF (end of archive) block to the tar archive. /// The end of the archive is indicated by two blocks consisting entirely of zero bytes. /// - void WriteEofBlock() + private void WriteEofBlock() { Array.Clear(blockBuffer, 0, blockBuffer.Length); buffer.WriteBlock(blockBuffer); @@ -400,20 +434,21 @@ void WriteEofBlock() } #region Instance Fields + /// /// bytes written for this entry so far /// - long currBytes; + private long currBytes; /// /// current 'Assembly' buffer length - /// - int assemblyBufferLength; + /// + private int assemblyBufferLength; /// /// Flag indicating wether this instance has been closed or not. /// - bool isClosed; + private bool isClosed; /// /// Size for the current entry @@ -421,7 +456,7 @@ void WriteEofBlock() protected long currSize; /// - /// single block working buffer + /// single block working buffer /// protected byte[] blockBuffer; @@ -439,6 +474,7 @@ void WriteEofBlock() /// the destination stream for the archive contents /// protected Stream outputStream; - #endregion + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs index 47a45bef3..f1b25b154 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs @@ -9,12 +9,13 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression /// /// This class is not thread safe. This is inherent in the API, due /// to the split of deflate and setInput. - /// + /// /// author of the original java version : Jochen Hoenicke /// public class Deflater { #region Deflater Documentation + /* * The Deflater can do the following state transitions: * @@ -49,8 +50,11 @@ public class Deflater * (7) At any time (7) * */ - #endregion + + #endregion Deflater Documentation + #region Public Constants + /// /// The best and slowest compression level. This tries to find very /// long and distant string repetitions. @@ -77,65 +81,73 @@ public class Deflater /// There is no need to use this constant at all. /// public const int DEFLATED = 8; - #endregion - #region Public Enum - - /// - /// Compression Level as an enum for safer use - /// - public enum CompressionLevel - { - /// - /// The best and slowest compression level. This tries to find very - /// long and distant string repetitions. - /// - BEST_COMPRESSION = Deflater.BEST_COMPRESSION, - - /// - /// The worst but fastest compression level. - /// - BEST_SPEED = Deflater.BEST_SPEED, - - /// - /// The default compression level. - /// - DEFAULT_COMPRESSION = Deflater.DEFAULT_COMPRESSION, - - /// - /// This level won't compress at all but output uncompressed blocks. - /// - NO_COMPRESSION = Deflater.NO_COMPRESSION, - - /// - /// The compression method. This is the only method supported so far. - /// There is no need to use this constant at all. - /// - DEFLATED = Deflater.DEFLATED - } - - #endregion - #region Local Constants - private const int IS_SETDICT = 0x01; + + #endregion Public Constants + + #region Public Enum + + /// + /// Compression Level as an enum for safer use + /// + public enum CompressionLevel + { + /// + /// The best and slowest compression level. This tries to find very + /// long and distant string repetitions. + /// + BEST_COMPRESSION = Deflater.BEST_COMPRESSION, + + /// + /// The worst but fastest compression level. + /// + BEST_SPEED = Deflater.BEST_SPEED, + + /// + /// The default compression level. + /// + DEFAULT_COMPRESSION = Deflater.DEFAULT_COMPRESSION, + + /// + /// This level won't compress at all but output uncompressed blocks. + /// + NO_COMPRESSION = Deflater.NO_COMPRESSION, + + /// + /// The compression method. This is the only method supported so far. + /// There is no need to use this constant at all. + /// + DEFLATED = Deflater.DEFLATED + } + + #endregion Public Enum + + #region Local Constants + + private const int IS_SETDICT = 0x01; private const int IS_FLUSHING = 0x04; private const int IS_FINISHING = 0x08; private const int INIT_STATE = 0x00; private const int SETDICT_STATE = 0x01; + // private static int INIT_FINISHING_STATE = 0x08; // private static int SETDICT_FINISHING_STATE = 0x09; private const int BUSY_STATE = 0x10; + private const int FLUSHING_STATE = 0x14; private const int FINISHING_STATE = 0x1c; private const int FINISHED_STATE = 0x1e; private const int CLOSED_STATE = 0x7f; - #endregion + + #endregion Local Constants + #region Constructors + /// /// Creates a new deflater with default compression level. /// public Deflater() : this(DEFAULT_COMPRESSION, false) { - } /// @@ -148,7 +160,6 @@ public Deflater() : this(DEFAULT_COMPRESSION, false) /// if lvl is out of range. public Deflater(int level) : this(level, false) { - } /// @@ -166,9 +177,12 @@ public Deflater(int level) : this(level, false) /// if lvl is out of range. public Deflater(int level, bool noZlibHeaderOrFooter) { - if (level == DEFAULT_COMPRESSION) { + if (level == DEFAULT_COMPRESSION) + { level = 6; - } else if (level < NO_COMPRESSION || level > BEST_COMPRESSION) { + } + else if (level < NO_COMPRESSION || level > BEST_COMPRESSION) + { throw new ArgumentOutOfRangeException(nameof(level)); } @@ -179,7 +193,8 @@ public Deflater(int level, bool noZlibHeaderOrFooter) SetLevel(level); Reset(); } - #endregion + + #endregion Constructors /// /// Resets the deflater. The deflater acts afterwards as if it was @@ -197,8 +212,10 @@ public void Reset() /// /// Gets the current adler checksum of the data that was processed so far. /// - public int Adler { - get { + public int Adler + { + get + { return engine.Adler; } } @@ -206,8 +223,10 @@ public int Adler { /// /// Gets the number of input bytes processed so far. /// - public long TotalIn { - get { + public long TotalIn + { + get + { return engine.TotalIn; } } @@ -215,8 +234,10 @@ public long TotalIn { /// /// Gets the number of output bytes so far. /// - public long TotalOut { - get { + public long TotalOut + { + get + { return totalOut; } } @@ -247,20 +268,24 @@ public void Finish() /// Returns true if the stream was finished and no more output bytes /// are available. /// - public bool IsFinished { - get { + public bool IsFinished + { + get + { return (state == FINISHED_STATE) && pending.IsFlushed; } } /// /// Returns true, if the input buffer is empty. - /// You should then call setInput(). + /// You should then call setInput(). /// NOTE: This method can also return true when the stream /// was finished. /// - public bool IsNeedingInput { - get { + public bool IsNeedingInput + { + get + { return engine.NeedsInput(); } } @@ -305,7 +330,8 @@ public void SetInput(byte[] input) /// public void SetInput(byte[] input, int offset, int count) { - if ((state & IS_FINISHING) != 0) { + if ((state & IS_FINISHING) != 0) + { throw new InvalidOperationException("Finish() already called"); } engine.SetInput(input, offset, count); @@ -322,13 +348,17 @@ public void SetInput(byte[] input, int offset, int count) /// public void SetLevel(int level) { - if (level == DEFAULT_COMPRESSION) { + if (level == DEFAULT_COMPRESSION) + { level = 6; - } else if (level < NO_COMPRESSION || level > BEST_COMPRESSION) { + } + else if (level < NO_COMPRESSION || level > BEST_COMPRESSION) + { throw new ArgumentOutOfRangeException(nameof(level)); } - if (this.level != level) { + if (this.level != level) + { this.level = level; engine.SetLevel(level); } @@ -398,27 +428,32 @@ public int Deflate(byte[] output, int offset, int length) { int origLength = length; - if (state == CLOSED_STATE) { + if (state == CLOSED_STATE) + { throw new InvalidOperationException("Deflater closed"); } - if (state < BUSY_STATE) { + if (state < BUSY_STATE) + { // output header int header = (DEFLATED + ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8; int level_flags = (level - 1) >> 1; - if (level_flags < 0 || level_flags > 3) { + if (level_flags < 0 || level_flags > 3) + { level_flags = 3; } header |= level_flags << 6; - if ((state & IS_SETDICT) != 0) { + if ((state & IS_SETDICT) != 0) + { // Dictionary was set header |= DeflaterConstants.PRESET_DICT; } header += 31 - (header % 31); pending.WriteShortMSB(header); - if ((state & IS_SETDICT) != 0) { + if ((state & IS_SETDICT) != 0) + { int chksum = engine.Adler; engine.ResetAdler(); pending.WriteShortMSB(chksum >> 16); @@ -428,29 +463,36 @@ public int Deflate(byte[] output, int offset, int length) state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING)); } - for (;;) { + for (; ; ) + { int count = pending.Flush(output, offset, length); offset += count; totalOut += count; length -= count; - if (length == 0 || state == FINISHED_STATE) { + if (length == 0 || state == FINISHED_STATE) + { break; } - if (!engine.Deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0)) { - switch (state) { + if (!engine.Deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0)) + { + switch (state) + { case BUSY_STATE: // We need more input now return origLength - length; + case FLUSHING_STATE: - if (level != NO_COMPRESSION) { + if (level != NO_COMPRESSION) + { /* We have to supply some lookahead. 8 bit lookahead * is needed by the zlib inflater, and we must fill * the next byte, so that all bits are flushed. */ int neededbits = 8 + ((-pending.BitCount) & 7); - while (neededbits > 0) { + while (neededbits > 0) + { /* write a static tree block consisting solely of * an EOF: */ @@ -460,11 +502,13 @@ public int Deflate(byte[] output, int offset, int length) } state = BUSY_STATE; break; + case FINISHING_STATE: pending.AlignToByte(); // Compressed data is complete. Write footer information if required. - if (!noZlibHeaderOrFooter) { + if (!noZlibHeaderOrFooter) + { int adler = engine.Adler; pending.WriteShortMSB(adler >> 16); pending.WriteShortMSB(adler & 0xffff); @@ -514,7 +558,8 @@ public void SetDictionary(byte[] dictionary) /// public void SetDictionary(byte[] dictionary, int index, int count) { - if (state != INIT_STATE) { + if (state != INIT_STATE) + { throw new InvalidOperationException(); } @@ -523,35 +568,37 @@ public void SetDictionary(byte[] dictionary, int index, int count) } #region Instance Fields + /// /// Compression level. /// - int level; + private int level; /// /// If true no Zlib/RFC1950 headers or footers are generated /// - bool noZlibHeaderOrFooter; + private bool noZlibHeaderOrFooter; /// /// The current state. /// - int state; + private int state; /// /// The total bytes of output written. /// - long totalOut; + private long totalOut; /// /// The pending output. /// - DeflaterPending pending; + private DeflaterPending pending; /// /// The deflater engine. /// - DeflaterEngine engine; - #endregion + private DeflaterEngine engine; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterConstants.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterConstants.cs index b66efb06e..b6d7f291b 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterConstants.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterConstants.cs @@ -39,108 +39,107 @@ public static class DeflaterConstants /// /// Internal compression engine constant - /// + /// public const int MAX_MATCH = 258; /// /// Internal compression engine constant - /// + /// public const int MIN_MATCH = 3; /// /// Internal compression engine constant - /// + /// public const int MAX_WBITS = 15; /// /// Internal compression engine constant - /// + /// public const int WSIZE = 1 << MAX_WBITS; /// /// Internal compression engine constant - /// + /// public const int WMASK = WSIZE - 1; /// /// Internal compression engine constant - /// + /// public const int HASH_BITS = DEFAULT_MEM_LEVEL + 7; /// /// Internal compression engine constant - /// + /// public const int HASH_SIZE = 1 << HASH_BITS; /// /// Internal compression engine constant - /// + /// public const int HASH_MASK = HASH_SIZE - 1; /// /// Internal compression engine constant - /// + /// public const int HASH_SHIFT = (HASH_BITS + MIN_MATCH - 1) / MIN_MATCH; /// /// Internal compression engine constant - /// + /// public const int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1; /// /// Internal compression engine constant - /// + /// public const int MAX_DIST = WSIZE - MIN_LOOKAHEAD; /// /// Internal compression engine constant - /// + /// public const int PENDING_BUF_SIZE = 1 << (DEFAULT_MEM_LEVEL + 8); /// /// Internal compression engine constant - /// + /// public static int MAX_BLOCK_SIZE = Math.Min(65535, PENDING_BUF_SIZE - 5); /// /// Internal compression engine constant - /// + /// public const int DEFLATE_STORED = 0; /// /// Internal compression engine constant - /// + /// public const int DEFLATE_FAST = 1; /// /// Internal compression engine constant - /// + /// public const int DEFLATE_SLOW = 2; /// /// Internal compression engine constant - /// + /// public static int[] GOOD_LENGTH = { 0, 4, 4, 4, 4, 8, 8, 8, 32, 32 }; /// /// Internal compression engine constant - /// + /// public static int[] MAX_LAZY = { 0, 4, 5, 6, 4, 16, 16, 32, 128, 258 }; /// /// Internal compression engine constant - /// + /// public static int[] NICE_LENGTH = { 0, 8, 16, 32, 16, 32, 128, 128, 258, 258 }; /// /// Internal compression engine constant - /// + /// public static int[] MAX_CHAIN = { 0, 4, 8, 32, 16, 32, 128, 256, 1024, 4096 }; /// /// Internal compression engine constant - /// + /// public static int[] COMPR_FUNC = { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2 }; - } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs index cfbfc0bf2..3a3bf6705 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs @@ -1,5 +1,5 @@ -using System; using ICSharpCode.SharpZipLib.Checksum; +using System; namespace ICSharpCode.SharpZipLib.Zip.Compression { @@ -19,7 +19,6 @@ public enum DeflateStrategy /// Filtered = 1, - /// /// This strategy will not look for string repetitions at all. It /// only encodes with Huffman trees (which means, that more common @@ -29,18 +28,17 @@ public enum DeflateStrategy } // DEFLATE ALGORITHM: - // + // // The uncompressed stream is inserted into the window array. When // the window array is full the first half is thrown away and the // second half is copied to the beginning. // // The head array is a hash table. Three characters build a hash value - // and they the value points to the corresponding index in window of + // and they the value points to the corresponding index in window of // the last string with this hash. The prev array implements a // linked list of matches with the same hash: prev[index & WMASK] points // to the previous index with the same hash. - // - + // /// /// Low level compression engine for deflate algorithm which uses a 32K sliding window @@ -49,10 +47,13 @@ public enum DeflateStrategy public class DeflaterEngine { #region Constants - const int TooFar = 4096; - #endregion + + private const int TooFar = 4096; + + #endregion Constants #region Constructors + /// /// Construct instance with pending buffer /// @@ -74,7 +75,7 @@ public DeflaterEngine(DeflaterPending pending) blockStart = strstart = 1; } - #endregion + #endregion Constructors /// /// Deflate drives actual compression of data @@ -85,7 +86,8 @@ public DeflaterEngine(DeflaterPending pending) public bool Deflate(bool flush, bool finish) { bool progress; - do { + do + { FillWindow(); bool canFlush = flush && (inputOff == inputEnd); @@ -95,16 +97,20 @@ public bool Deflate(bool flush, bool finish) + lookahead + "], " + compressionFunction + "," + canFlush); } #endif - switch (compressionFunction) { + switch (compressionFunction) + { case DeflaterConstants.DEFLATE_STORED: progress = DeflateStored(canFlush, finish); break; + case DeflaterConstants.DEFLATE_FAST: progress = DeflateFast(canFlush, finish); break; + case DeflaterConstants.DEFLATE_SLOW: progress = DeflateSlow(canFlush, finish); break; + default: throw new InvalidOperationException("unknown compressionFunction"); } @@ -121,19 +127,23 @@ public bool Deflate(bool flush, bool finish) /// The number of bytes of data to use as input. public void SetInput(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset)); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count)); } - if (inputOff < inputEnd) { + if (inputOff < inputEnd) + { throw new InvalidOperationException("Old input was not completely processed"); } @@ -142,7 +152,8 @@ public void SetInput(byte[] buffer, int offset, int count) /* We want to throw an ArrayIndexOutOfBoundsException early. The * check is very tricky: it also handles integer wrap around. */ - if ((offset > end) || (end > buffer.Length)) { + if ((offset > end) || (end > buffer.Length)) + { throw new ArgumentOutOfRangeException(nameof(count)); } @@ -153,7 +164,7 @@ public void SetInput(byte[] buffer, int offset, int count) /// /// Determines if more input is needed. - /// + /// /// Return true if input is needed via SetInput public bool NeedsInput() { @@ -169,17 +180,19 @@ public bool NeedsInput() public void SetDictionary(byte[] buffer, int offset, int length) { #if DebugDeflation - if (DeflaterConstants.DEBUGGING && (strstart != 1) ) + if (DeflaterConstants.DEBUGGING && (strstart != 1) ) { throw new InvalidOperationException("strstart not 1"); } #endif adler.Update(new ArraySegment(buffer, offset, length)); - if (length < DeflaterConstants.MIN_MATCH) { + if (length < DeflaterConstants.MIN_MATCH) + { return; } - if (length > DeflaterConstants.MAX_DIST) { + if (length > DeflaterConstants.MAX_DIST) + { offset += length - DeflaterConstants.MAX_DIST; length = DeflaterConstants.MAX_DIST; } @@ -188,7 +201,8 @@ public void SetDictionary(byte[] buffer, int offset, int length) UpdateHash(); --length; - while (--length > 0) { + while (--length > 0) + { InsertString(); strstart++; } @@ -198,7 +212,7 @@ public void SetDictionary(byte[] buffer, int offset, int length) /// /// Reset internal state - /// + /// public void Reset() { huffman.Reset(); @@ -209,18 +223,20 @@ public void Reset() prevAvailable = false; matchLen = DeflaterConstants.MIN_MATCH - 1; - for (int i = 0; i < DeflaterConstants.HASH_SIZE; i++) { + for (int i = 0; i < DeflaterConstants.HASH_SIZE; i++) + { head[i] = 0; } - for (int i = 0; i < DeflaterConstants.WSIZE; i++) { + for (int i = 0; i < DeflaterConstants.WSIZE; i++) + { prev[i] = 0; } } /// /// Reset Adler checksum - /// + /// public void ResetAdler() { adler.Reset(); @@ -228,30 +244,37 @@ public void ResetAdler() /// /// Get current value of Adler checksum - /// - public int Adler { - get { + /// + public int Adler + { + get + { return unchecked((int)adler.Value); } } /// /// Total data processed - /// - public long TotalIn { - get { + /// + public long TotalIn + { + get + { return totalIn; } } /// /// Get/set the deflate strategy - /// - public DeflateStrategy Strategy { - get { + /// + public DeflateStrategy Strategy + { + get + { return strategy; } - set { + set + { strategy = value; } } @@ -262,7 +285,8 @@ public DeflateStrategy Strategy { /// The value to set the level to. public void SetLevel(int level) { - if ((level < 0) || (level > 9)) { + if ((level < 0) || (level > 9)) + { throw new ArgumentOutOfRangeException(nameof(level)); } @@ -271,17 +295,19 @@ public void SetLevel(int level) niceLength = DeflaterConstants.NICE_LENGTH[level]; max_chain = DeflaterConstants.MAX_CHAIN[level]; - if (DeflaterConstants.COMPR_FUNC[level] != compressionFunction) { - + if (DeflaterConstants.COMPR_FUNC[level] != compressionFunction) + { #if DebugDeflation if (DeflaterConstants.DEBUGGING) { Console.WriteLine("Change from " + compressionFunction + " to " + DeflaterConstants.COMPR_FUNC[level]); } #endif - switch (compressionFunction) { + switch (compressionFunction) + { case DeflaterConstants.DEFLATE_STORED: - if (strstart > blockStart) { + if (strstart > blockStart) + { huffman.FlushStoredBlock(window, blockStart, strstart - blockStart, false); blockStart = strstart; @@ -290,7 +316,8 @@ public void SetLevel(int level) break; case DeflaterConstants.DEFLATE_FAST: - if (strstart > blockStart) { + if (strstart > blockStart) + { huffman.FlushBlock(window, blockStart, strstart - blockStart, false); blockStart = strstart; @@ -298,10 +325,12 @@ public void SetLevel(int level) break; case DeflaterConstants.DEFLATE_SLOW: - if (prevAvailable) { + if (prevAvailable) + { huffman.TallyLit(window[strstart - 1] & 0xff); } - if (strstart > blockStart) { + if (strstart > blockStart) + { huffman.FlushBlock(window, blockStart, strstart - blockStart, false); blockStart = strstart; } @@ -321,17 +350,20 @@ public void FillWindow() /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ - if (strstart >= DeflaterConstants.WSIZE + DeflaterConstants.MAX_DIST) { + if (strstart >= DeflaterConstants.WSIZE + DeflaterConstants.MAX_DIST) + { SlideWindow(); } /* If there is not enough lookahead, but still some input left, * read in the input */ - if (lookahead < DeflaterConstants.MIN_LOOKAHEAD && inputOff < inputEnd) { + if (lookahead < DeflaterConstants.MIN_LOOKAHEAD && inputOff < inputEnd) + { int more = 2 * DeflaterConstants.WSIZE - lookahead - strstart; - if (more > inputEnd - inputOff) { + if (more > inputEnd - inputOff) + { more = inputEnd - inputOff; } @@ -343,12 +375,13 @@ public void FillWindow() lookahead += more; } - if (lookahead >= DeflaterConstants.MIN_MATCH) { + if (lookahead >= DeflaterConstants.MIN_MATCH) + { UpdateHash(); } } - void UpdateHash() + private void UpdateHash() { /* if (DEBUGGING) { @@ -363,16 +396,16 @@ void UpdateHash() /// value for this hash. /// /// The previous hash value - int InsertString() + private int InsertString() { short match; int hash = ((ins_h << DeflaterConstants.HASH_SHIFT) ^ window[strstart + (DeflaterConstants.MIN_MATCH - 1)]) & DeflaterConstants.HASH_MASK; #if DebugDeflation - if (DeflaterConstants.DEBUGGING) + if (DeflaterConstants.DEBUGGING) { - if (hash != (((window[strstart] << (2*HASH_SHIFT)) ^ - (window[strstart + 1] << HASH_SHIFT) ^ + if (hash != (((window[strstart] << (2*HASH_SHIFT)) ^ + (window[strstart + 1] << HASH_SHIFT) ^ (window[strstart + 2])) & HASH_MASK)) { throw new SharpZipBaseException("hash inconsistent: " + hash + "/" +window[strstart] + "," @@ -387,7 +420,7 @@ int InsertString() return match & 0xffff; } - void SlideWindow() + private void SlideWindow() { Array.Copy(window, DeflaterConstants.WSIZE, window, 0, DeflaterConstants.WSIZE); matchStart -= DeflaterConstants.WSIZE; @@ -396,20 +429,22 @@ void SlideWindow() // Slide the hash table (could be avoided with 32 bit values // at the expense of memory usage). - for (int i = 0; i < DeflaterConstants.HASH_SIZE; ++i) { + for (int i = 0; i < DeflaterConstants.HASH_SIZE; ++i) + { int m = head[i] & 0xffff; head[i] = (short)(m >= DeflaterConstants.WSIZE ? (m - DeflaterConstants.WSIZE) : 0); } // Slide the prev table. - for (int i = 0; i < DeflaterConstants.WSIZE; i++) { + for (int i = 0; i < DeflaterConstants.WSIZE; i++) + { int m = prev[i] & 0xffff; prev[i] = (short)(m >= DeflaterConstants.WSIZE ? (m - DeflaterConstants.WSIZE) : 0); } } /// - /// Find the best (longest) string in the window matching the + /// Find the best (longest) string in the window matching the /// string starting at strstart. /// /// Preconditions: @@ -418,136 +453,150 @@ void SlideWindow() /// /// /// True if a match greater than the minimum length is found - bool FindLongestMatch( int curMatch ) + private bool FindLongestMatch(int curMatch) { - int match; - int scan = strstart; - // scanMax is the highest position that we can look at - int scanMax = scan + Math.Min( DeflaterConstants.MAX_MATCH, lookahead ) - 1; - int limit = Math.Max( scan - DeflaterConstants.MAX_DIST, 0 ); - - byte[] window = this.window; - short[] prev = this.prev; - int chainLength = this.max_chain; - int niceLength = Math.Min( this.niceLength, lookahead ); - - matchLen = Math.Max( matchLen, DeflaterConstants.MIN_MATCH - 1 ); - - if (scan + matchLen > scanMax) return false; - - byte scan_end1 = window[scan + matchLen - 1]; - byte scan_end = window[scan + matchLen]; - - // Do not waste too much time if we already have a good match: - if (matchLen >= this.goodLength) chainLength >>= 2; - - do - { - match = curMatch; - scan = strstart; - - if (window[match + matchLen] != scan_end - || window[match + matchLen - 1] != scan_end1 - || window[match] != window[scan] - || window[++match] != window[++scan]) - { - continue; - } - - // scan is set to strstart+1 and the comparison passed, so - // scanMax - scan is the maximum number of bytes we can compare. - // below we compare 8 bytes at a time, so first we compare - // (scanMax - scan) % 8 bytes, so the remainder is a multiple of 8 - - switch( (scanMax - scan) % 8 ) - { - case 1: if (window[++scan] == window[++match]) break; - break; - case 2: if (window[++scan] == window[++match] - && window[++scan] == window[++match]) break; - break; - case 3: if (window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match]) break; - break; - case 4: if (window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match]) break; - break; - case 5: if (window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match]) break; - break; - case 6: if (window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match]) break; - break; - case 7: if (window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match]) break; - break; - } - - if (window[scan] == window[match]) - { - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart + 258 unless lookahead is - * exhausted first. - */ - do - { - if (scan == scanMax) - { - ++scan; // advance to first position not matched - ++match; - - break; - } - } - while (window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match]); - } - - if (scan - strstart > matchLen) - { - #if DebugDeflation + int match; + int scan = strstart; + // scanMax is the highest position that we can look at + int scanMax = scan + Math.Min(DeflaterConstants.MAX_MATCH, lookahead) - 1; + int limit = Math.Max(scan - DeflaterConstants.MAX_DIST, 0); + + byte[] window = this.window; + short[] prev = this.prev; + int chainLength = this.max_chain; + int niceLength = Math.Min(this.niceLength, lookahead); + + matchLen = Math.Max(matchLen, DeflaterConstants.MIN_MATCH - 1); + + if (scan + matchLen > scanMax) return false; + + byte scan_end1 = window[scan + matchLen - 1]; + byte scan_end = window[scan + matchLen]; + + // Do not waste too much time if we already have a good match: + if (matchLen >= this.goodLength) chainLength >>= 2; + + do + { + match = curMatch; + scan = strstart; + + if (window[match + matchLen] != scan_end + || window[match + matchLen - 1] != scan_end1 + || window[match] != window[scan] + || window[++match] != window[++scan]) + { + continue; + } + + // scan is set to strstart+1 and the comparison passed, so + // scanMax - scan is the maximum number of bytes we can compare. + // below we compare 8 bytes at a time, so first we compare + // (scanMax - scan) % 8 bytes, so the remainder is a multiple of 8 + + switch ((scanMax - scan) % 8) + { + case 1: + if (window[++scan] == window[++match]) break; + break; + + case 2: + if (window[++scan] == window[++match] + && window[++scan] == window[++match]) break; + break; + + case 3: + if (window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match]) break; + break; + + case 4: + if (window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match]) break; + break; + + case 5: + if (window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match]) break; + break; + + case 6: + if (window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match]) break; + break; + + case 7: + if (window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match]) break; + break; + } + + if (window[scan] == window[match]) + { + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart + 258 unless lookahead is + * exhausted first. + */ + do + { + if (scan == scanMax) + { + ++scan; // advance to first position not matched + ++match; + + break; + } + } + while (window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match] + && window[++scan] == window[++match]); + } + + if (scan - strstart > matchLen) + { +#if DebugDeflation if (DeflaterConstants.DEBUGGING && (ins_h == 0) ) Console.Error.WriteLine("Found match: " + curMatch + "-" + (scan - strstart)); - #endif +#endif - matchStart = curMatch; - matchLen = scan - strstart; + matchStart = curMatch; + matchLen = scan - strstart; - if (matchLen >= niceLength) - break; - - scan_end1 = window[scan - 1]; - scan_end = window[scan]; - } - } while ((curMatch = (prev[curMatch & DeflaterConstants.WMASK] & 0xffff)) > limit && 0 != --chainLength ); + if (matchLen >= niceLength) + break; - return matchLen >= DeflaterConstants.MIN_MATCH; - } + scan_end1 = window[scan - 1]; + scan_end = window[scan]; + } + } while ((curMatch = (prev[curMatch & DeflaterConstants.WMASK] & 0xffff)) > limit && 0 != --chainLength); + + return matchLen >= DeflaterConstants.MIN_MATCH; + } - bool DeflateStored(bool flush, bool finish) + private bool DeflateStored(bool flush, bool finish) { - if (!flush && (lookahead == 0)) { + if (!flush && (lookahead == 0)) + { return false; } @@ -558,15 +607,17 @@ bool DeflateStored(bool flush, bool finish) if ((storedLength >= DeflaterConstants.MAX_BLOCK_SIZE) || // Block is full (blockStart < DeflaterConstants.WSIZE && storedLength >= DeflaterConstants.MAX_DIST) || // Block may move out of window - flush) { + flush) + { bool lastBlock = finish; - if (storedLength > DeflaterConstants.MAX_BLOCK_SIZE) { + if (storedLength > DeflaterConstants.MAX_BLOCK_SIZE) + { storedLength = DeflaterConstants.MAX_BLOCK_SIZE; lastBlock = false; } #if DebugDeflation - if (DeflaterConstants.DEBUGGING) + if (DeflaterConstants.DEBUGGING) { Console.WriteLine("storedBlock[" + storedLength + "," + lastBlock + "]"); } @@ -579,21 +630,25 @@ bool DeflateStored(bool flush, bool finish) return true; } - bool DeflateFast(bool flush, bool finish) + private bool DeflateFast(bool flush, bool finish) { - if (lookahead < DeflaterConstants.MIN_LOOKAHEAD && !flush) { + if (lookahead < DeflaterConstants.MIN_LOOKAHEAD && !flush) + { return false; } - while (lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush) { - if (lookahead == 0) { + while (lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush) + { + if (lookahead == 0) + { // We are flushing everything huffman.FlushBlock(window, blockStart, strstart - blockStart, finish); blockStart = strstart; return false; } - if (strstart > 2 * DeflaterConstants.WSIZE - DeflaterConstants.MIN_LOOKAHEAD) { + if (strstart > 2 * DeflaterConstants.WSIZE - DeflaterConstants.MIN_LOOKAHEAD) + { /* slide window, as FindLongestMatch needs this. * This should only happen when flushing and the window * is almost full. @@ -606,10 +661,11 @@ bool DeflateFast(bool flush, bool finish) (hashHead = InsertString()) != 0 && strategy != DeflateStrategy.HuffmanOnly && strstart - hashHead <= DeflaterConstants.MAX_DIST && - FindLongestMatch(hashHead)) { + FindLongestMatch(hashHead)) + { // longestMatch sets matchStart and matchLen #if DebugDeflation - if (DeflaterConstants.DEBUGGING) + if (DeflaterConstants.DEBUGGING) { for (int i = 0 ; i < matchLen; i++) { if (window[strstart + i] != window[matchStart + i]) { @@ -622,30 +678,39 @@ bool DeflateFast(bool flush, bool finish) bool full = huffman.TallyDist(strstart - matchStart, matchLen); lookahead -= matchLen; - if (matchLen <= max_lazy && lookahead >= DeflaterConstants.MIN_MATCH) { - while (--matchLen > 0) { + if (matchLen <= max_lazy && lookahead >= DeflaterConstants.MIN_MATCH) + { + while (--matchLen > 0) + { ++strstart; InsertString(); } ++strstart; - } else { + } + else + { strstart += matchLen; - if (lookahead >= DeflaterConstants.MIN_MATCH - 1) { + if (lookahead >= DeflaterConstants.MIN_MATCH - 1) + { UpdateHash(); } } matchLen = DeflaterConstants.MIN_MATCH - 1; - if (!full) { + if (!full) + { continue; } - } else { + } + else + { // No match found huffman.TallyLit(window[strstart] & 0xff); ++strstart; --lookahead; } - if (huffman.IsFull()) { + if (huffman.IsFull()) + { bool lastBlock = finish && (lookahead == 0); huffman.FlushBlock(window, blockStart, strstart - blockStart, lastBlock); blockStart = strstart; @@ -655,22 +720,26 @@ bool DeflateFast(bool flush, bool finish) return true; } - bool DeflateSlow(bool flush, bool finish) + private bool DeflateSlow(bool flush, bool finish) { - if (lookahead < DeflaterConstants.MIN_LOOKAHEAD && !flush) { + if (lookahead < DeflaterConstants.MIN_LOOKAHEAD && !flush) + { return false; } - while (lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush) { - if (lookahead == 0) { - if (prevAvailable) { + while (lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush) + { + if (lookahead == 0) + { + if (prevAvailable) + { huffman.TallyLit(window[strstart - 1] & 0xff); } prevAvailable = false; // We are flushing everything #if DebugDeflation - if (DeflaterConstants.DEBUGGING && !flush) + if (DeflaterConstants.DEBUGGING && !flush) { throw new SharpZipBaseException("Not flushing, but no lookahead"); } @@ -681,7 +750,8 @@ bool DeflateSlow(bool flush, bool finish) return false; } - if (strstart >= 2 * DeflaterConstants.WSIZE - DeflaterConstants.MIN_LOOKAHEAD) { + if (strstart >= 2 * DeflaterConstants.WSIZE - DeflaterConstants.MIN_LOOKAHEAD) + { /* slide window, as FindLongestMatch needs this. * This should only happen when flushing and the window * is almost full. @@ -691,28 +761,30 @@ bool DeflateSlow(bool flush, bool finish) int prevMatch = matchStart; int prevLen = matchLen; - if (lookahead >= DeflaterConstants.MIN_MATCH) { - + if (lookahead >= DeflaterConstants.MIN_MATCH) + { int hashHead = InsertString(); if (strategy != DeflateStrategy.HuffmanOnly && hashHead != 0 && strstart - hashHead <= DeflaterConstants.MAX_DIST && - FindLongestMatch(hashHead)) { - + FindLongestMatch(hashHead)) + { // longestMatch sets matchStart and matchLen // Discard match if too small and too far away - if (matchLen <= 5 && (strategy == DeflateStrategy.Filtered || (matchLen == DeflaterConstants.MIN_MATCH && strstart - matchStart > TooFar))) { + if (matchLen <= 5 && (strategy == DeflateStrategy.Filtered || (matchLen == DeflaterConstants.MIN_MATCH && strstart - matchStart > TooFar))) + { matchLen = DeflaterConstants.MIN_MATCH - 1; } } } // previous match was better - if ((prevLen >= DeflaterConstants.MIN_MATCH) && (matchLen <= prevLen)) { + if ((prevLen >= DeflaterConstants.MIN_MATCH) && (matchLen <= prevLen)) + { #if DebugDeflation - if (DeflaterConstants.DEBUGGING) + if (DeflaterConstants.DEBUGGING) { for (int i = 0 ; i < matchLen; i++) { if (window[strstart-1+i] != window[prevMatch + i]) @@ -722,10 +794,12 @@ bool DeflateSlow(bool flush, bool finish) #endif huffman.TallyDist(strstart - 1 - prevMatch, prevLen); prevLen -= 2; - do { + do + { strstart++; lookahead--; - if (lookahead >= DeflaterConstants.MIN_MATCH) { + if (lookahead >= DeflaterConstants.MIN_MATCH) + { InsertString(); } } while (--prevLen > 0); @@ -734,8 +808,11 @@ bool DeflateSlow(bool flush, bool finish) lookahead--; prevAvailable = false; matchLen = DeflaterConstants.MIN_MATCH - 1; - } else { - if (prevAvailable) { + } + else + { + if (prevAvailable) + { huffman.TallyLit(window[strstart - 1] & 0xff); } prevAvailable = true; @@ -743,9 +820,11 @@ bool DeflateSlow(bool flush, bool finish) lookahead--; } - if (huffman.IsFull()) { + if (huffman.IsFull()) + { int len = strstart - blockStart; - if (prevAvailable) { + if (prevAvailable) + { len--; } bool lastBlock = (finish && (lookahead == 0) && !prevAvailable); @@ -760,36 +839,39 @@ bool DeflateSlow(bool flush, bool finish) #region Instance Fields // Hash index of string to be inserted - int ins_h; + private int ins_h; /// /// Hashtable, hashing three characters to an index for window, so - /// that window[index]..window[index+2] have this hash code. + /// that window[index]..window[index+2] have this hash code. /// Note that the array should really be unsigned short, so you need /// to and the values with 0xffff. /// - short[] head; + private short[] head; /// /// prev[index & WMASK] points to the previous index that has the - /// same hash code as the string starting at index. This way + /// same hash code as the string starting at index. This way /// entries with the same hash code are in a linked list. /// Note that the array should really be unsigned short, so you need /// to and the values with 0xffff. /// - short[] prev; + private short[] prev; + + private int matchStart; - int matchStart; // Length of best match - int matchLen; + private int matchLen; + // Set if previous match exists - bool prevAvailable; - int blockStart; + private bool prevAvailable; + + private int blockStart; /// /// Points to the current character in the window. /// - int strstart; + private int strstart; /// /// lookahead is the number of characters starting at strstart in @@ -797,49 +879,50 @@ bool DeflateSlow(bool flush, bool finish) /// So window[strstart] until window[strstart+lookahead-1] are valid /// characters. /// - int lookahead; + private int lookahead; /// - /// This array contains the part of the uncompressed stream that + /// This array contains the part of the uncompressed stream that /// is of relevance. The current character is indexed by strstart. /// - byte[] window; + private byte[] window; - DeflateStrategy strategy; - int max_chain, max_lazy, niceLength, goodLength; + private DeflateStrategy strategy; + private int max_chain, max_lazy, niceLength, goodLength; /// /// The current compression function. /// - int compressionFunction; + private int compressionFunction; /// /// The input data for compression. /// - byte[] inputBuf; + private byte[] inputBuf; /// /// The total bytes of input read. /// - long totalIn; + private long totalIn; /// /// The offset into inputBuf, where input data starts. /// - int inputOff; + private int inputOff; /// /// The end offset of the input data. /// - int inputEnd; + private int inputEnd; - DeflaterPending pending; - DeflaterHuffman huffman; + private DeflaterPending pending; + private DeflaterHuffman huffman; /// /// The adler checksum /// - Adler32 adler; - #endregion + private Adler32 adler; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs index d26e79339..2f71366fc 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs @@ -4,36 +4,39 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression { /// /// This is the DeflaterHuffman class. - /// + /// /// This class is not thread safe. This is inherent in the API, due /// to the split of Deflate and SetInput. - /// + /// /// author of the original java version : Jochen Hoenicke /// public class DeflaterHuffman { - const int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6); - const int LITERAL_NUM = 286; + private const int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6); + private const int LITERAL_NUM = 286; // Number of distance codes - const int DIST_NUM = 30; + private const int DIST_NUM = 30; + // Number of codes used to transfer bit lengths - const int BITLEN_NUM = 19; + private const int BITLEN_NUM = 19; // repeat previous bit length 3-6 times (2 bits of repeat count) - const int REP_3_6 = 16; + private const int REP_3_6 = 16; + // repeat a zero length 3-10 times (3 bits of repeat count) - const int REP_3_10 = 17; + private const int REP_3_10 = 17; + // repeat a zero length 11-138 times (7 bits of repeat count) - const int REP_11_138 = 18; + private const int REP_11_138 = 18; - const int EOF_SYMBOL = 256; + private const int EOF_SYMBOL = 256; // The lengths of the bit length codes are sent in order of decreasing // probability, to avoid transmitting the lengths for unused bit length codes. - static readonly int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + private static readonly int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - static readonly byte[] bit4Reverse = { + private static readonly byte[] bit4Reverse = { 0, 8, 4, @@ -52,14 +55,15 @@ public class DeflaterHuffman 15 }; - static short[] staticLCodes; - static byte[] staticLLength; - static short[] staticDCodes; - static byte[] staticDLength; + private static short[] staticLCodes; + private static byte[] staticLLength; + private static short[] staticDCodes; + private static byte[] staticDLength; - class Tree + private class Tree { #region Instance Fields + public short[] freqs; public byte[] length; @@ -68,13 +72,15 @@ class Tree public int numCodes; - short[] codes; - readonly int[] bl_counts; - readonly int maxLength; - DeflaterHuffman dh; - #endregion + private short[] codes; + private readonly int[] bl_counts; + private readonly int maxLength; + private DeflaterHuffman dh; + + #endregion Instance Fields #region Constructors + public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength) { this.dh = dh; @@ -84,14 +90,15 @@ public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength) bl_counts = new int[maxLength]; } - #endregion + #endregion Constructors /// /// Resets the internal state of the tree /// public void Reset() { - for (int i = 0; i < freqs.Length; i++) { + for (int i = 0; i < freqs.Length; i++) + { freqs[i] = 0; } codes = null; @@ -116,11 +123,13 @@ public void WriteSymbol(int code) public void CheckEmpty() { bool empty = true; - for (int i = 0; i < freqs.Length; i++) { + for (int i = 0; i < freqs.Length; i++) + { empty &= freqs[i] == 0; } - if (!empty) { + if (!empty) + { throw new SharpZipBaseException("!Empty"); } } @@ -151,7 +160,8 @@ public void BuildCodes() // //Console.WriteLine("buildCodes: "+freqs.Length); // } - for (int bits = 0; bits < maxLength; bits++) { + for (int bits = 0; bits < maxLength; bits++) + { nextCode[bits] = code; code += bl_counts[bits] << (15 - bits); @@ -162,15 +172,16 @@ public void BuildCodes() } #if DebugDeflation - if ( DeflaterConstants.DEBUGGING && (code != 65536) ) + if ( DeflaterConstants.DEBUGGING && (code != 65536) ) { throw new SharpZipBaseException("Inconsistent bl_counts!"); } #endif - for (int i = 0; i < numCodes; i++) { + for (int i = 0; i < numCodes; i++) + { int bits = length[i]; - if (bits > 0) { - + if (bits > 0) + { // if (DeflaterConstants.DEBUGGING) { // //Console.WriteLine("codes["+i+"] = rev(" + nextCode[bits-1]+"), // +bits); @@ -197,13 +208,16 @@ public void BuildTree() int[] heap = new int[numSymbols]; int heapLen = 0; int maxCode = 0; - for (int n = 0; n < numSymbols; n++) { + for (int n = 0; n < numSymbols; n++) + { int freq = freqs[n]; - if (freq != 0) { + if (freq != 0) + { // Insert n into heap int pos = heapLen++; int ppos; - while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq) { + while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq) + { heap[pos] = heap[ppos]; pos = ppos; } @@ -218,7 +232,8 @@ public void BuildTree() * literals to avoid this case. We don't care about order in * this case, both literals get a 1 bit code. */ - while (heapLen < 2) { + while (heapLen < 2) + { int node = maxCode < 2 ? ++maxCode : 0; heap[heapLen++] = node; } @@ -229,7 +244,8 @@ public void BuildTree() int[] childs = new int[4 * heapLen - 2]; int[] values = new int[2 * heapLen - 1]; int numNodes = numLeafs; - for (int i = 0; i < heapLen; i++) { + for (int i = 0; i < heapLen; i++) + { int node = heap[i]; childs[2 * i] = node; childs[2 * i + 1] = -1; @@ -240,7 +256,8 @@ public void BuildTree() /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ - do { + do + { int first = heap[0]; int last = heap[--heapLen]; @@ -248,8 +265,10 @@ public void BuildTree() int ppos = 0; int path = 1; - while (path < heapLen) { - if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]]) { + while (path < heapLen) + { + if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]]) + { path++; } @@ -262,12 +281,12 @@ public void BuildTree() * it shouldn't go too deep. */ int lastVal = values[last]; - while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal) { + while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal) + { heap[path] = heap[ppos]; } heap[path] = last; - int second = heap[0]; // Create a new node father of first and second @@ -281,8 +300,10 @@ public void BuildTree() ppos = 0; path = 1; - while (path < heapLen) { - if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]]) { + while (path < heapLen) + { + if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]]) + { path++; } @@ -292,13 +313,15 @@ public void BuildTree() } // Now propagate the new element down along path - while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal) { + while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal) + { heap[path] = heap[ppos]; } heap[path] = last; } while (heapLen > 1); - if (heap[0] != childs.Length / 2 - 1) { + if (heap[0] != childs.Length / 2 - 1) + { throw new SharpZipBaseException("Heap invariant violated"); } @@ -312,7 +335,8 @@ public void BuildTree() public int GetEncodedLength() { int len = 0; - for (int i = 0; i < freqs.Length; i++) { + for (int i = 0; i < freqs.Length; i++) + { len += freqs[i] * length[i]; } return len; @@ -330,16 +354,21 @@ public void CalcBLFreq(Tree blTree) int curlen = -1; /* length of current code */ int i = 0; - while (i < numCodes) { + while (i < numCodes) + { count = 1; int nextlen = length[i]; - if (nextlen == 0) { + if (nextlen == 0) + { max_count = 138; min_count = 3; - } else { + } + else + { max_count = 6; min_count = 3; - if (curlen != nextlen) { + if (curlen != nextlen) + { blTree.freqs[nextlen]++; count = 0; } @@ -347,20 +376,29 @@ public void CalcBLFreq(Tree blTree) curlen = nextlen; i++; - while (i < numCodes && curlen == length[i]) { + while (i < numCodes && curlen == length[i]) + { i++; - if (++count >= max_count) { + if (++count >= max_count) + { break; } } - if (count < min_count) { + if (count < min_count) + { blTree.freqs[curlen] += (short)count; - } else if (curlen != 0) { + } + else if (curlen != 0) + { blTree.freqs[REP_3_6]++; - } else if (count <= 10) { + } + else if (count <= 10) + { blTree.freqs[REP_3_10]++; - } else { + } + else + { blTree.freqs[REP_11_138]++; } } @@ -378,16 +416,21 @@ public void WriteTree(Tree blTree) int curlen = -1; // length of current code int i = 0; - while (i < numCodes) { + while (i < numCodes) + { count = 1; int nextlen = length[i]; - if (nextlen == 0) { + if (nextlen == 0) + { max_count = 138; min_count = 3; - } else { + } + else + { max_count = 6; min_count = 3; - if (curlen != nextlen) { + if (curlen != nextlen) + { blTree.WriteSymbol(nextlen); count = 0; } @@ -395,38 +438,49 @@ public void WriteTree(Tree blTree) curlen = nextlen; i++; - while (i < numCodes && curlen == length[i]) { + while (i < numCodes && curlen == length[i]) + { i++; - if (++count >= max_count) { + if (++count >= max_count) + { break; } } - if (count < min_count) { - while (count-- > 0) { + if (count < min_count) + { + while (count-- > 0) + { blTree.WriteSymbol(curlen); } - } else if (curlen != 0) { + } + else if (curlen != 0) + { blTree.WriteSymbol(REP_3_6); dh.pending.WriteBits(count - 3, 2); - } else if (count <= 10) { + } + else if (count <= 10) + { blTree.WriteSymbol(REP_3_10); dh.pending.WriteBits(count - 3, 3); - } else { + } + else + { blTree.WriteSymbol(REP_11_138); dh.pending.WriteBits(count - 11, 7); } } } - void BuildLength(int[] childs) + private void BuildLength(int[] childs) { this.length = new byte[freqs.Length]; int numNodes = childs.Length / 2; int numLeafs = (numNodes + 1) / 2; int overflow = 0; - for (int i = 0; i < maxLength; i++) { + for (int i = 0; i < maxLength; i++) + { bl_counts[i] = 0; } @@ -434,15 +488,20 @@ void BuildLength(int[] childs) int[] lengths = new int[numNodes]; lengths[numNodes - 1] = 0; - for (int i = numNodes - 1; i >= 0; i--) { - if (childs[2 * i + 1] != -1) { + for (int i = numNodes - 1; i >= 0; i--) + { + if (childs[2 * i + 1] != -1) + { int bitLength = lengths[i] + 1; - if (bitLength > maxLength) { + if (bitLength > maxLength) + { bitLength = maxLength; overflow++; } lengths[childs[2 * i]] = lengths[childs[2 * i + 1]] = bitLength; - } else { + } + else + { // A leaf node int bitLength = lengths[i]; bl_counts[bitLength - 1]++; @@ -458,19 +517,23 @@ void BuildLength(int[] childs) // } // } - if (overflow == 0) { + if (overflow == 0) + { return; } int incrBitLen = maxLength - 1; - do { + do + { // Find the first bit length which could increase: - while (bl_counts[--incrBitLen] == 0) { + while (bl_counts[--incrBitLen] == 0) + { } // Move this node one down and remove a corresponding // number of overflow nodes. - do { + do + { bl_counts[incrBitLen]--; bl_counts[++incrBitLen]++; overflow -= 1 << (maxLength - 1 - incrBitLen); @@ -492,11 +555,14 @@ void BuildLength(int[] childs) * array. */ int nodePtr = 2 * numLeafs; - for (int bits = maxLength; bits != 0; bits--) { + for (int bits = maxLength; bits != 0; bits--) + { int n = bl_counts[bits - 1]; - while (n > 0) { + while (n > 0) + { int childPtr = 2 * childs[nodePtr++]; - if (childs[childPtr + 1] == -1) { + if (childs[childPtr + 1] == -1) + { // We found another leaf length[childs[childPtr]] = (byte)bits; n--; @@ -511,25 +577,27 @@ void BuildLength(int[] childs) // } // } } - } #region Instance Fields + /// /// Pending buffer to use /// public DeflaterPending pending; - Tree literalTree; - Tree distTree; - Tree blTree; + private Tree literalTree; + private Tree distTree; + private Tree blTree; // Buffer for distances - short[] d_buf; - byte[] l_buf; - int last_lit; - int extra_bits; - #endregion + private short[] d_buf; + + private byte[] l_buf; + private int last_lit; + private int extra_bits; + + #endregion Instance Fields static DeflaterHuffman() { @@ -539,22 +607,26 @@ static DeflaterHuffman() staticLLength = new byte[LITERAL_NUM]; int i = 0; - while (i < 144) { + while (i < 144) + { staticLCodes[i] = BitReverse((0x030 + i) << 8); staticLLength[i++] = 8; } - while (i < 256) { + while (i < 256) + { staticLCodes[i] = BitReverse((0x190 - 144 + i) << 7); staticLLength[i++] = 9; } - while (i < 280) { + while (i < 280) + { staticLCodes[i] = BitReverse((0x000 - 256 + i) << 9); staticLLength[i++] = 7; } - while (i < LITERAL_NUM) { + while (i < LITERAL_NUM) + { staticLCodes[i] = BitReverse((0x0c0 - 280 + i) << 8); staticLLength[i++] = 8; } @@ -562,7 +634,8 @@ static DeflaterHuffman() // Distance codes staticDCodes = new short[DIST_NUM]; staticDLength = new byte[DIST_NUM]; - for (i = 0; i < DIST_NUM; i++) { + for (i = 0; i < DIST_NUM; i++) + { staticDCodes[i] = BitReverse(i << 11); staticDLength[i] = 5; } @@ -586,7 +659,7 @@ public DeflaterHuffman(DeflaterPending pending) /// /// Reset internal state - /// + /// public void Reset() { last_lit = 0; @@ -608,7 +681,8 @@ public void SendAllTrees(int blTreeCodes) pending.WriteBits(literalTree.numCodes - 257, 5); pending.WriteBits(distTree.numCodes - 1, 5); pending.WriteBits(blTreeCodes - 4, 4); - for (int rank = 0; rank < blTreeCodes; rank++) { + for (int rank = 0; rank < blTreeCodes; rank++) + { pending.WriteBits(blTree.length[BL_ORDER[rank]], 3); } literalTree.WriteTree(blTree); @@ -626,10 +700,12 @@ public void SendAllTrees(int blTreeCodes) /// public void CompressBlock() { - for (int i = 0; i < last_lit; i++) { + for (int i = 0; i < last_lit; i++) + { int litlen = l_buf[i] & 0xff; int dist = d_buf[i]; - if (dist-- != 0) { + if (dist-- != 0) + { // if (DeflaterConstants.DEBUGGING) { // Console.Write("["+(dist+1)+","+(litlen+3)+"]: "); // } @@ -638,7 +714,8 @@ public void CompressBlock() literalTree.WriteSymbol(lc); int bits = (lc - 261) / 4; - if (bits > 0 && bits <= 5) { + if (bits > 0 && bits <= 5) + { pending.WriteBits(litlen & ((1 << bits) - 1), bits); } @@ -646,10 +723,13 @@ public void CompressBlock() distTree.WriteSymbol(dc); bits = dc / 2 - 1; - if (bits > 0) { + if (bits > 0) + { pending.WriteBits(dist & ((1 << bits) - 1), bits); } - } else { + } + else + { // if (DeflaterConstants.DEBUGGING) { // if (litlen > 32 && litlen < 127) { // Console.Write("("+(char)litlen+"): "); @@ -700,7 +780,7 @@ public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, /// /// Flush block to output with compression - /// + /// /// Data to flush /// Index of first byte to flush /// Count of bytes to flush @@ -721,8 +801,10 @@ public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool l blTree.BuildTree(); int blTreeCodes = 4; - for (int i = 18; i > blTreeCodes; i--) { - if (blTree.length[BL_ORDER[i]] > 0) { + for (int i = 18; i > blTreeCodes; i--) + { + if (blTree.length[BL_ORDER[i]] > 0) + { blTreeCodes = i + 1; } } @@ -731,18 +813,22 @@ public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool l extra_bits; int static_len = extra_bits; - for (int i = 0; i < LITERAL_NUM; i++) { + for (int i = 0; i < LITERAL_NUM; i++) + { static_len += literalTree.freqs[i] * staticLLength[i]; } - for (int i = 0; i < DIST_NUM; i++) { + for (int i = 0; i < DIST_NUM; i++) + { static_len += distTree.freqs[i] * staticDLength[i]; } - if (opt_len >= static_len) { + if (opt_len >= static_len) + { // Force static trees opt_len = static_len; } - if (storedOffset >= 0 && storedLength + 4 < opt_len >> 3) { + if (storedOffset >= 0 && storedLength + 4 < opt_len >> 3) + { // Store Block // if (DeflaterConstants.DEBUGGING) { @@ -750,14 +836,18 @@ public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool l // + " <= " + static_len); // } FlushStoredBlock(stored, storedOffset, storedLength, lastBlock); - } else if (opt_len == static_len) { + } + else if (opt_len == static_len) + { // Encode with static tree pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3); literalTree.SetStaticCodes(staticLCodes, staticLLength); distTree.SetStaticCodes(staticDCodes, staticDLength); CompressBlock(); Reset(); - } else { + } + else + { // Encode with dynamic tree pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3); SendAllTrees(blTreeCodes); @@ -812,19 +902,20 @@ public bool TallyDist(int distance, int length) int lc = Lcode(length - 3); literalTree.freqs[lc]++; - if (lc >= 265 && lc < 285) { + if (lc >= 265 && lc < 285) + { extra_bits += (lc - 261) / 4; } int dc = Dcode(distance - 1); distTree.freqs[dc]++; - if (dc >= 4) { + if (dc >= 4) + { extra_bits += dc / 2 - 1; } return IsFull(); } - /// /// Reverse the bits of a 16 bit value. /// @@ -838,24 +929,27 @@ public static short BitReverse(int toReverse) bit4Reverse[toReverse >> 12]); } - static int Lcode(int length) + private static int Lcode(int length) { - if (length == 255) { + if (length == 255) + { return 285; } int code = 257; - while (length >= 8) { + while (length >= 8) + { code += 4; length >>= 1; } return code + length; } - static int Dcode(int distance) + private static int Dcode(int distance) { int code = 0; - while (distance >= 4) { + while (distance >= 4) + { code += 2; distance >>= 1; } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterPending.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterPending.cs index 2c6c22e1d..80d3e2142 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterPending.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterPending.cs @@ -2,7 +2,7 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression { /// /// This class stores the pending output of the Deflater. - /// + /// /// author of the original java version : Jochen Hoenicke /// public class DeflaterPending : PendingBuffer diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs index e68009fce..5eace7053 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs @@ -1,13 +1,13 @@ -using System; using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using System; namespace ICSharpCode.SharpZipLib.Zip.Compression { /// /// Inflater is used to decompress data that has been compressed according /// to the "deflate" standard described in rfc1951. - /// + /// /// By default Zlib (rfc1950) headers and footers are expected in the input. /// You can use constructor public Inflater(bool noHeader) passing true /// if there is no Zlib header information @@ -32,10 +32,11 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression public class Inflater { #region Constants/Readonly + /// /// Copy lengths for literal codes 257..285 /// - static readonly int[] CPLENS = { + private static readonly int[] CPLENS = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 }; @@ -43,7 +44,7 @@ public class Inflater /// /// Extra bits for literal codes 257..285 /// - static readonly int[] CPLEXT = { + private static readonly int[] CPLEXT = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; @@ -51,7 +52,7 @@ public class Inflater /// /// Copy offsets for distance codes 0..29 /// - static readonly int[] CPDIST = { + private static readonly int[] CPDIST = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 @@ -60,7 +61,7 @@ public class Inflater /// /// Extra bits for distance codes /// - static readonly int[] CPDEXT = { + private static readonly int[] CPDEXT = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 @@ -69,78 +70,85 @@ public class Inflater /// /// These are the possible states for an inflater /// - const int DECODE_HEADER = 0; - const int DECODE_DICT = 1; - const int DECODE_BLOCKS = 2; - const int DECODE_STORED_LEN1 = 3; - const int DECODE_STORED_LEN2 = 4; - const int DECODE_STORED = 5; - const int DECODE_DYN_HEADER = 6; - const int DECODE_HUFFMAN = 7; - const int DECODE_HUFFMAN_LENBITS = 8; - const int DECODE_HUFFMAN_DIST = 9; - const int DECODE_HUFFMAN_DISTBITS = 10; - const int DECODE_CHKSUM = 11; - const int FINISHED = 12; - #endregion + private const int DECODE_HEADER = 0; + + private const int DECODE_DICT = 1; + private const int DECODE_BLOCKS = 2; + private const int DECODE_STORED_LEN1 = 3; + private const int DECODE_STORED_LEN2 = 4; + private const int DECODE_STORED = 5; + private const int DECODE_DYN_HEADER = 6; + private const int DECODE_HUFFMAN = 7; + private const int DECODE_HUFFMAN_LENBITS = 8; + private const int DECODE_HUFFMAN_DIST = 9; + private const int DECODE_HUFFMAN_DISTBITS = 10; + private const int DECODE_CHKSUM = 11; + private const int FINISHED = 12; + + #endregion Constants/Readonly #region Instance Fields + /// /// This variable contains the current state. /// - int mode; + private int mode; /// /// The adler checksum of the dictionary or of the decompressed /// stream, as it is written in the header resp. footer of the - /// compressed stream. + /// compressed stream. /// Only valid if mode is DECODE_DICT or DECODE_CHKSUM. /// - int readAdler; + private int readAdler; /// /// The number of bits needed to complete the current state. This /// is valid, if mode is DECODE_DICT, DECODE_CHKSUM, /// DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS. /// - int neededBits; - int repLength; - int repDist; - int uncomprLen; + private int neededBits; + + private int repLength; + private int repDist; + private int uncomprLen; /// /// True, if the last block flag was set in the last block of the /// inflated stream. This means that the stream ends after the /// current block. /// - bool isLastBlock; + private bool isLastBlock; /// /// The total number of inflated bytes. /// - long totalOut; + private long totalOut; /// /// The total number of bytes set with setInput(). This is not the /// value returned by the TotalIn property, since this also includes the /// unprocessed input. /// - long totalIn; + private long totalIn; /// /// This variable stores the noHeader flag that was given to the constructor. - /// True means, that the inflated stream doesn't contain a Zlib header or + /// True means, that the inflated stream doesn't contain a Zlib header or /// footer. /// - bool noHeader; - readonly StreamManipulator input; - OutputWindow outputWindow; - InflaterDynHeader dynHeader; - InflaterHuffmanTree litlenTree, distTree; - Adler32 adler; - #endregion + private bool noHeader; + + private readonly StreamManipulator input; + private OutputWindow outputWindow; + private InflaterDynHeader dynHeader; + private InflaterHuffmanTree litlenTree, distTree; + private Adler32 adler; + + #endregion Instance Fields #region Constructors + /// /// Creates a new inflater or RFC1951 decompressor /// RFC1950/Zlib headers and footers will be expected in the input data @@ -154,9 +162,9 @@ public Inflater() : this(false) /// /// /// True if no RFC1950/Zlib header and footer fields are expected in the input data - /// + /// /// This is used for GZIPed/Zipped input. - /// + /// /// For compatibility with /// Sun JDK you should provide one byte of input more than needed in /// this case. @@ -169,7 +177,8 @@ public Inflater(bool noHeader) outputWindow = new OutputWindow(); mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER; } - #endregion + + #endregion Constructors /// /// Resets the inflater so that a new stream can be decompressed. All @@ -201,18 +210,21 @@ public void Reset() private bool DecodeHeader() { int header = input.PeekBits(16); - if (header < 0) { + if (header < 0) + { return false; } input.DropBits(16); // The header is written in "wrong" byte order header = ((header << 8) | (header >> 8)) & 0xffff; - if (header % 31 != 0) { + if (header % 31 != 0) + { throw new SharpZipBaseException("Header checksum illegal"); } - if ((header & 0x0f00) != (Deflater.DEFLATED << 8)) { + if ((header & 0x0f00) != (Deflater.DEFLATED << 8)) + { throw new SharpZipBaseException("Compression Method unknown"); } @@ -223,9 +235,12 @@ private bool DecodeHeader() int max_wbits = ((header & 0x7000) >> 12) + 8; */ - if ((header & 0x0020) == 0) { // Dictionary flag? + if ((header & 0x0020) == 0) + { // Dictionary flag? mode = DECODE_BLOCKS; - } else { + } + else + { mode = DECODE_DICT; neededBits = 32; } @@ -240,9 +255,11 @@ private bool DecodeHeader() /// private bool DecodeDict() { - while (neededBits > 0) { + while (neededBits > 0) + { int dictByte = input.PeekBits(8); - if (dictByte < 0) { + if (dictByte < 0) + { return false; } input.DropBits(8); @@ -265,22 +282,30 @@ private bool DecodeDict() private bool DecodeHuffman() { int free = outputWindow.GetFreeSpace(); - while (free >= 258) { + while (free >= 258) + { int symbol; - switch (mode) { + switch (mode) + { case DECODE_HUFFMAN: // This is the inner loop so it is optimized a bit - while (((symbol = litlenTree.GetSymbol(input)) & ~0xff) == 0) { + while (((symbol = litlenTree.GetSymbol(input)) & ~0xff) == 0) + { outputWindow.Write(symbol); - if (--free < 258) { + if (--free < 258) + { return true; } } - if (symbol < 257) { - if (symbol < 0) { + if (symbol < 257) + { + if (symbol < 0) + { return false; - } else { + } + else + { // symbol == 256: end of block distTree = null; litlenTree = null; @@ -289,19 +314,24 @@ private bool DecodeHuffman() } } - try { + try + { repLength = CPLENS[symbol - 257]; neededBits = CPLEXT[symbol - 257]; - } catch (Exception) { + } + catch (Exception) + { throw new SharpZipBaseException("Illegal rep length code"); } goto case DECODE_HUFFMAN_LENBITS; // fall through case DECODE_HUFFMAN_LENBITS: - if (neededBits > 0) { + if (neededBits > 0) + { mode = DECODE_HUFFMAN_LENBITS; int i = input.PeekBits(neededBits); - if (i < 0) { + if (i < 0) + { return false; } input.DropBits(neededBits); @@ -312,24 +342,30 @@ private bool DecodeHuffman() case DECODE_HUFFMAN_DIST: symbol = distTree.GetSymbol(input); - if (symbol < 0) { + if (symbol < 0) + { return false; } - try { + try + { repDist = CPDIST[symbol]; neededBits = CPDEXT[symbol]; - } catch (Exception) { + } + catch (Exception) + { throw new SharpZipBaseException("Illegal rep dist code"); } goto case DECODE_HUFFMAN_DISTBITS; // fall through case DECODE_HUFFMAN_DISTBITS: - if (neededBits > 0) { + if (neededBits > 0) + { mode = DECODE_HUFFMAN_DISTBITS; int i = input.PeekBits(neededBits); - if (i < 0) { + if (i < 0) + { return false; } input.DropBits(neededBits); @@ -359,9 +395,11 @@ private bool DecodeHuffman() /// private bool DecodeChksum() { - while (neededBits > 0) { + while (neededBits > 0) + { int chkByte = input.PeekBits(8); - if (chkByte < 0) { + if (chkByte < 0) + { return false; } input.DropBits(8); @@ -369,7 +407,8 @@ private bool DecodeChksum() neededBits -= 8; } - if ((int)adler.Value != readAdler) { + if ((int)adler.Value != readAdler) + { throw new SharpZipBaseException("Adler chksum doesn't match: " + (int)adler.Value + " vs. " + readAdler); } @@ -388,7 +427,8 @@ private bool DecodeChksum() /// private bool Decode() { - switch (mode) { + switch (mode) + { case DECODE_HEADER: return DecodeHeader(); @@ -399,11 +439,15 @@ private bool Decode() return DecodeChksum(); case DECODE_BLOCKS: - if (isLastBlock) { - if (noHeader) { + if (isLastBlock) + { + if (noHeader) + { mode = FINISHED; return false; - } else { + } + else + { input.SkipToByteBoundary(); neededBits = 32; mode = DECODE_CHKSUM; @@ -412,33 +456,40 @@ private bool Decode() } int type = input.PeekBits(3); - if (type < 0) { + if (type < 0) + { return false; } input.DropBits(3); isLastBlock |= (type & 1) != 0; - switch (type >> 1) { + switch (type >> 1) + { case DeflaterConstants.STORED_BLOCK: input.SkipToByteBoundary(); mode = DECODE_STORED_LEN1; break; + case DeflaterConstants.STATIC_TREES: litlenTree = InflaterHuffmanTree.defLitLenTree; distTree = InflaterHuffmanTree.defDistTree; mode = DECODE_HUFFMAN; break; + case DeflaterConstants.DYN_TREES: dynHeader = new InflaterDynHeader(input); mode = DECODE_DYN_HEADER; break; + default: throw new SharpZipBaseException("Unknown block type " + type); } return true; - case DECODE_STORED_LEN1: { - if ((uncomprLen = input.PeekBits(16)) < 0) { + case DECODE_STORED_LEN1: + { + if ((uncomprLen = input.PeekBits(16)) < 0) + { return false; } input.DropBits(16); @@ -446,23 +497,28 @@ private bool Decode() } goto case DECODE_STORED_LEN2; // fall through - case DECODE_STORED_LEN2: { + case DECODE_STORED_LEN2: + { int nlen = input.PeekBits(16); - if (nlen < 0) { + if (nlen < 0) + { return false; } input.DropBits(16); - if (nlen != (uncomprLen ^ 0xffff)) { + if (nlen != (uncomprLen ^ 0xffff)) + { throw new SharpZipBaseException("broken uncompressed block"); } mode = DECODE_STORED; } goto case DECODE_STORED; // fall through - case DECODE_STORED: { + case DECODE_STORED: + { int more = outputWindow.CopyStored(input, uncomprLen); uncomprLen -= more; - if (uncomprLen == 0) { + if (uncomprLen == 0) + { mode = DECODE_BLOCKS; return true; } @@ -470,7 +526,8 @@ private bool Decode() } case DECODE_DYN_HEADER: - if (!dynHeader.AttemptRead()) { + if (!dynHeader.AttemptRead()) + { return false; } @@ -530,25 +587,30 @@ public void SetDictionary(byte[] buffer) /// public void SetDictionary(byte[] buffer, int index, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (index < 0) { + if (index < 0) + { throw new ArgumentOutOfRangeException(nameof(index)); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count)); } - if (!IsNeedingDictionary) { + if (!IsNeedingDictionary) + { throw new InvalidOperationException("Dictionary is not needed"); } adler.Update(new ArraySegment(buffer, index, count)); - if ((int)adler.Value != readAdler) { + if ((int)adler.Value != readAdler) + { throw new SharpZipBaseException("Wrong adler checksum"); } adler.Reset(); @@ -614,7 +676,8 @@ public void SetInput(byte[] buffer, int index, int count) /// public int Inflate(byte[] buffer) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } @@ -650,25 +713,31 @@ public int Inflate(byte[] buffer) /// public int Inflate(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count), "count cannot be negative"); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset), "offset cannot be negative"); } - if (offset + count > buffer.Length) { + if (offset + count > buffer.Length) + { throw new ArgumentException("count exceeds buffer bounds"); } // Special case: count may be zero - if (count == 0) { - if (!IsFinished) { // -jr- 08-Nov-2003 INFLATE_BUG fix.. + if (count == 0) + { + if (!IsFinished) + { // -jr- 08-Nov-2003 INFLATE_BUG fix.. Decode(); } return 0; @@ -676,8 +745,10 @@ public int Inflate(byte[] buffer, int offset, int count) int bytesCopied = 0; - do { - if (mode != DECODE_CHKSUM) { + do + { + if (mode != DECODE_CHKSUM) + { /* Don't give away any output, if we are waiting for the * checksum in the input stream. * @@ -686,13 +757,15 @@ public int Inflate(byte[] buffer, int offset, int count) * implies more output can be produced. */ int more = outputWindow.CopyOutput(buffer, offset, count); - if (more > 0) { + if (more > 0) + { adler.Update(new ArraySegment(buffer, offset, more)); offset += more; bytesCopied += more; totalOut += (long)more; count -= more; - if (count == 0) { + if (count == 0) + { return bytesCopied; } } @@ -703,11 +776,13 @@ public int Inflate(byte[] buffer, int offset, int count) /// /// Returns true, if the input buffer is empty. - /// You should then call setInput(). + /// You should then call setInput(). /// NOTE: This method also returns true when the stream is finished. /// - public bool IsNeedingInput { - get { + public bool IsNeedingInput + { + get + { return input.IsNeedingInput; } } @@ -715,8 +790,10 @@ public bool IsNeedingInput { /// /// Returns true, if a preset dictionary is needed to inflate the input. /// - public bool IsNeedingDictionary { - get { + public bool IsNeedingDictionary + { + get + { return mode == DECODE_DICT && neededBits == 0; } } @@ -725,8 +802,10 @@ public bool IsNeedingDictionary { /// Returns true, if the inflater has finished. This means, that no /// input is needed and no output can be produced. /// - public bool IsFinished { - get { + public bool IsFinished + { + get + { return mode == FINISHED && outputWindow.GetAvailable() == 0; } } @@ -740,8 +819,10 @@ public bool IsFinished { /// /// the adler checksum. /// - public int Adler { - get { + public int Adler + { + get + { return IsNeedingDictionary ? readAdler : (int)adler.Value; } } @@ -752,8 +833,10 @@ public int Adler { /// /// the total number of output bytes. /// - public long TotalOut { - get { + public long TotalOut + { + get + { return totalOut; } } @@ -764,8 +847,10 @@ public long TotalOut { /// /// The total number of bytes of processed input bytes. /// - public long TotalIn { - get { + public long TotalIn + { + get + { return totalIn - (long)RemainingInput; } } @@ -778,9 +863,11 @@ public long TotalIn { /// /// The number of bytes of the input which have not been processed. /// - public int RemainingInput { + public int RemainingInput + { // TODO: This should be a long? - get { + get + { return input.AvailableBytes; } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs index b36b32c2b..8e0196b11 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs @@ -1,29 +1,29 @@ +using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using System; using System.Collections.Generic; -using ICSharpCode.SharpZipLib.Zip.Compression.Streams; namespace ICSharpCode.SharpZipLib.Zip.Compression { - class InflaterDynHeader + internal class InflaterDynHeader { #region Constants // maximum number of literal/length codes - const int LITLEN_MAX = 286; + private const int LITLEN_MAX = 286; // maximum number of distance codes - const int DIST_MAX = 30; + private const int DIST_MAX = 30; // maximum data code lengths to read - const int CODELEN_MAX = LITLEN_MAX + DIST_MAX; + private const int CODELEN_MAX = LITLEN_MAX + DIST_MAX; // maximum meta code length codes to read - const int META_MAX = 19; + private const int META_MAX = 19; - static readonly int[] MetaCodeLengthIndex = + private static readonly int[] MetaCodeLengthIndex = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - #endregion + #endregion Constants /// /// Continue decoding header from until more bits are needed or decoding has been completed @@ -41,7 +41,6 @@ public InflaterDynHeader(StreamManipulator input) private IEnumerable CreateStateMachine() { - // Read initial code length counts from header while (!input.TryGetBits(5, ref litLenCodeCount, 257)) yield return false; while (!input.TryGetBits(5, ref distanceCodeCount, 1)) yield return false; @@ -53,7 +52,7 @@ private IEnumerable CreateStateMachine() if (metaCodeCount > META_MAX) throw new ValueOutOfRangeException(nameof(metaCodeCount)); // Load code lengths for the meta tree from the header bits - for (int i=0; i < metaCodeCount; i++) + for (int i = 0; i < metaCodeCount; i++) { while (!input.TryGetBits(3, ref codeLengths, MetaCodeLengthIndex[i])) yield return false; } @@ -80,14 +79,13 @@ private IEnumerable CreateStateMachine() if (symbol == 16) // Repeat last code length 3..6 times { - if (index == 0) throw new StreamDecodingException("Cannot repeat previous code length when no other code length has been read"); codeLength = codeLengths[index - 1]; // 2 bits + 3, [3..6] - while(!input.TryGetBits(2, ref repeatCount, 3)) yield return false; + while (!input.TryGetBits(2, ref repeatCount, 3)) yield return false; } else if (symbol == 17) // Repeat zero 3..10 times { @@ -146,10 +144,8 @@ public InflaterHuffmanTree DistanceTree private InflaterHuffmanTree litLenTree; private InflaterHuffmanTree distTree; - int litLenCodeCount, distanceCodeCount, metaCodeCount; - - #endregion + private int litLenCodeCount, distanceCodeCount, metaCodeCount; + #endregion Instance Fields } - } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs index ffb141984..e9158f3d0 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs @@ -1,6 +1,6 @@ +using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using System; using System.Collections.Generic; -using ICSharpCode.SharpZipLib.Zip.Compression.Streams; namespace ICSharpCode.SharpZipLib.Zip.Compression { @@ -10,12 +10,16 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression public class InflaterHuffmanTree { #region Constants - const int MAX_BITLEN = 15; - #endregion + + private const int MAX_BITLEN = 15; + + #endregion Constants #region Instance Fields - short[] tree; - #endregion + + private short[] tree; + + #endregion Instance Fields /// /// Literal length tree @@ -29,35 +33,44 @@ public class InflaterHuffmanTree static InflaterHuffmanTree() { - try { + try + { byte[] codeLengths = new byte[288]; int i = 0; - while (i < 144) { + while (i < 144) + { codeLengths[i++] = 8; } - while (i < 256) { + while (i < 256) + { codeLengths[i++] = 9; } - while (i < 280) { + while (i < 280) + { codeLengths[i++] = 7; } - while (i < 288) { + while (i < 288) + { codeLengths[i++] = 8; } defLitLenTree = new InflaterHuffmanTree(codeLengths); codeLengths = new byte[32]; i = 0; - while (i < 32) { + while (i < 32) + { codeLengths[i++] = 5; } defDistTree = new InflaterHuffmanTree(codeLengths); - } catch (Exception) { + } + catch (Exception) + { throw new SharpZipBaseException("InflaterHuffmanTree: static tree length illegal"); } } #region Constructors + /// /// Constructs a Huffman tree from the array of code lengths. /// @@ -68,26 +81,31 @@ public InflaterHuffmanTree(IList codeLengths) { BuildTree(codeLengths); } - #endregion - void BuildTree(IList codeLengths) + #endregion Constructors + + private void BuildTree(IList codeLengths) { int[] blCount = new int[MAX_BITLEN + 1]; int[] nextCode = new int[MAX_BITLEN + 1]; - for (int i = 0; i < codeLengths.Count; i++) { + for (int i = 0; i < codeLengths.Count; i++) + { int bits = codeLengths[i]; - if (bits > 0) { + if (bits > 0) + { blCount[bits]++; } } int code = 0; int treeSize = 512; - for (int bits = 1; bits <= MAX_BITLEN; bits++) { + for (int bits = 1; bits <= MAX_BITLEN; bits++) + { nextCode[bits] = code; code += blCount[bits] << (16 - bits); - if (bits >= 10) { + if (bits >= 10) + { /* We need an extra table for bit lengths >= 10. */ int start = nextCode[bits] & 0x1ff80; int end = code & 0x1ff80; @@ -96,7 +114,7 @@ void BuildTree(IList codeLengths) } /* -jr comment this out! doesnt work for dynamic trees and pkzip 2.04g - if (code != 65536) + if (code != 65536) { throw new SharpZipBaseException("Code lengths don't add up properly."); } @@ -106,40 +124,48 @@ void BuildTree(IList codeLengths) */ tree = new short[treeSize]; int treePtr = 512; - for (int bits = MAX_BITLEN; bits >= 10; bits--) { + for (int bits = MAX_BITLEN; bits >= 10; bits--) + { int end = code & 0x1ff80; code -= blCount[bits] << (16 - bits); int start = code & 0x1ff80; - for (int i = start; i < end; i += 1 << 7) { + for (int i = start; i < end; i += 1 << 7) + { tree[DeflaterHuffman.BitReverse(i)] = (short)((-treePtr << 4) | bits); treePtr += 1 << (bits - 9); } } - for (int i = 0; i < codeLengths.Count; i++) { + for (int i = 0; i < codeLengths.Count; i++) + { int bits = codeLengths[i]; - if (bits == 0) { + if (bits == 0) + { continue; } code = nextCode[bits]; int revcode = DeflaterHuffman.BitReverse(code); - if (bits <= 9) { - do { + if (bits <= 9) + { + do + { tree[revcode] = (short)((i << 4) | bits); revcode += 1 << bits; } while (revcode < 512); - } else { + } + else + { int subTree = tree[revcode & 511]; int treeLen = 1 << (subTree & 15); subTree = -(subTree >> 4); - do { + do + { tree[subTree | (revcode >> 9)] = (short)((i << 4) | bits); revcode += 1 << bits; } while (revcode < treeLen); } nextCode[bits] = code + (1 << (16 - bits)); } - } /// @@ -204,4 +230,3 @@ public int GetSymbol(StreamManipulator input) } } } - diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs index fd6cbf0c8..6ed7e4ab8 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs @@ -1,31 +1,32 @@ -using System; - namespace ICSharpCode.SharpZipLib.Zip.Compression { /// /// This class is general purpose class for writing data to a buffer. - /// + /// /// It allows you to write bits as well as bytes /// Based on DeflaterPending.java - /// + /// /// author of the original java version : Jochen Hoenicke /// public class PendingBuffer { #region Instance Fields + /// /// Internal work buffer /// - readonly byte[] buffer; + private readonly byte[] buffer; + + private int start; + private int end; - int start; - int end; + private uint bits; + private int bitCount; - uint bits; - int bitCount; - #endregion + #endregion Instance Fields #region Constructors + /// /// construct instance using default buffer size of 4096 /// @@ -44,7 +45,7 @@ public PendingBuffer(int bufferSize) buffer = new byte[bufferSize]; } - #endregion + #endregion Constructors /// /// Clear internal state/buffers @@ -116,7 +117,7 @@ public void WriteInt(int value) public void WriteBlock(byte[] block, int offset, int length) { #if DebugDeflation - if (DeflaterConstants.DEBUGGING && (start != 0) ) + if (DeflaterConstants.DEBUGGING && (start != 0) ) { throw new SharpZipBaseException("Debug check: start != 0"); } @@ -128,8 +129,10 @@ public void WriteBlock(byte[] block, int offset, int length) /// /// The number of bits written to the buffer /// - public int BitCount { - get { + public int BitCount + { + get + { return bitCount; } } @@ -140,14 +143,16 @@ public int BitCount { public void AlignToByte() { #if DebugDeflation - if (DeflaterConstants.DEBUGGING && (start != 0) ) + if (DeflaterConstants.DEBUGGING && (start != 0) ) { throw new SharpZipBaseException("Debug check: start != 0"); } #endif - if (bitCount > 0) { + if (bitCount > 0) + { buffer[end++] = unchecked((byte)bits); - if (bitCount > 8) { + if (bitCount > 8) + { buffer[end++] = unchecked((byte)(bits >> 8)); } } @@ -163,7 +168,7 @@ public void AlignToByte() public void WriteBits(int b, int count) { #if DebugDeflation - if (DeflaterConstants.DEBUGGING && (start != 0) ) + if (DeflaterConstants.DEBUGGING && (start != 0) ) { throw new SharpZipBaseException("Debug check: start != 0"); } @@ -174,7 +179,8 @@ public void WriteBits(int b, int count) #endif bits |= (uint)(b << bitCount); bitCount += count; - if (bitCount >= 16) { + if (bitCount >= 16) + { buffer[end++] = unchecked((byte)bits); buffer[end++] = unchecked((byte)(bits >> 8)); bits >>= 16; @@ -189,7 +195,7 @@ public void WriteBits(int b, int count) public void WriteShortMSB(int s) { #if DebugDeflation - if (DeflaterConstants.DEBUGGING && (start != 0) ) + if (DeflaterConstants.DEBUGGING && (start != 0) ) { throw new SharpZipBaseException("Debug check: start != 0"); } @@ -201,8 +207,10 @@ public void WriteShortMSB(int s) /// /// Indicates if buffer has been flushed /// - public bool IsFlushed { - get { + public bool IsFlushed + { + get + { return end == 0; } } @@ -217,18 +225,22 @@ public bool IsFlushed { /// The number of bytes flushed. public int Flush(byte[] output, int offset, int length) { - if (bitCount >= 8) { + if (bitCount >= 8) + { buffer[end++] = unchecked((byte)bits); bits >>= 8; bitCount -= 8; } - if (length > end - start) { + if (length > end - start) + { length = end - start; System.Array.Copy(buffer, start, output, offset, length); start = 0; end = 0; - } else { + } + else + { System.Array.Copy(buffer, start, output, offset, length); start += length; } @@ -245,7 +257,7 @@ public int Flush(byte[] output, int offset, int length) public byte[] ToByteArray() { AlignToByte(); - + byte[] result = new byte[end - start]; System.Array.Copy(buffer, start, result, 0, result.Length); start = 0; diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs index ad49c3f63..f08947d0e 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs @@ -1,18 +1,19 @@ +using ICSharpCode.SharpZipLib.Encryption; using System; using System.IO; using System.Security.Cryptography; -using ICSharpCode.SharpZipLib.Encryption; namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams { /// /// A special stream deflating or compressing the bytes that are /// written to it. It uses a Deflater to perform actual deflating.
- /// Authors of the original java version : Tom Tromey, Jochen Hoenicke + /// Authors of the original java version : Tom Tromey, Jochen Hoenicke ///
public class DeflaterOutputStream : Stream { #region Constructors + /// /// Creates a new DeflaterOutputStream with a default Deflater and default buffer size. /// @@ -63,31 +64,32 @@ public DeflaterOutputStream(Stream baseOutputStream, Deflater deflater) /// public DeflaterOutputStream(Stream baseOutputStream, Deflater deflater, int bufferSize) { - if (baseOutputStream == null) { + if (baseOutputStream == null) + { throw new ArgumentNullException(nameof(baseOutputStream)); } - if (baseOutputStream.CanWrite == false) { + if (baseOutputStream.CanWrite == false) + { throw new ArgumentException("Must support writing", nameof(baseOutputStream)); } - if (deflater == null) { - throw new ArgumentNullException(nameof(deflater)); - } - - if (bufferSize < 512) { + if (bufferSize < 512) + { throw new ArgumentOutOfRangeException(nameof(bufferSize)); } baseOutputStream_ = baseOutputStream; buffer_ = new byte[bufferSize]; - deflater_ = deflater; + deflater_ = deflater ?? throw new ArgumentNullException(nameof(deflater)); } - #endregion + + #endregion Constructors #region Public API + /// - /// Finishes the stream by calling finish() on the deflater. + /// Finishes the stream by calling finish() on the deflater. /// /// /// Not all input is deflated @@ -95,27 +97,33 @@ public DeflaterOutputStream(Stream baseOutputStream, Deflater deflater, int buff public virtual void Finish() { deflater_.Finish(); - while (!deflater_.IsFinished) { + while (!deflater_.IsFinished) + { int len = deflater_.Deflate(buffer_, 0, buffer_.Length); - if (len <= 0) { + if (len <= 0) + { break; } - if (cryptoTransform_ != null) { + if (cryptoTransform_ != null) + { EncryptBlock(buffer_, 0, len); } baseOutputStream_.Write(buffer_, 0, len); } - if (!deflater_.IsFinished) { + if (!deflater_.IsFinished) + { throw new SharpZipBaseException("Can't deflate all input?"); } baseOutputStream_.Flush(); - if (cryptoTransform_ != null) { - if (cryptoTransform_ is ZipAESTransform) { + if (cryptoTransform_ != null) + { + if (cryptoTransform_ is ZipAESTransform) + { AESAuthCode = ((ZipAESTransform)cryptoTransform_).GetAuthCode(); } cryptoTransform_.Dispose(); @@ -133,19 +141,21 @@ public virtual void Finish() /// /// Allows client to determine if an entry can be patched after its added /// - public bool CanPatchEntries { - get { + public bool CanPatchEntries + { + get + { return baseOutputStream_.CanSeek; } } - #endregion + #endregion Public API #region Encryption - string password; + private string password; - ICryptoTransform cryptoTransform_; + private ICryptoTransform cryptoTransform_; /// /// Returns the 10 byte AUTH CODE to be appended immediately following the AES data stream. @@ -156,14 +166,20 @@ public bool CanPatchEntries { /// Get/set the password used for encryption. /// /// When set to null or if the password is empty no encryption is performed - public string Password { - get { + public string Password + { + get + { return password; } - set { - if ((value != null) && (value.Length == 0)) { + set + { + if ((value != null) && (value.Length == 0)) + { password = null; - } else { + } + else + { password = value; } } @@ -193,7 +209,7 @@ protected void EncryptBlock(byte[] buffer, int offset, int length) protected void InitializePassword(string password) { var pkManaged = new PkzipClassicManaged(); - byte[] key = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(password)); + byte[] key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(password)); cryptoTransform_ = pkManaged.CreateEncryptor(key, null); } @@ -214,9 +230,10 @@ protected void InitializeAESPassword(ZipEntry entry, string rawPassword, pwdVerifier = ((ZipAESTransform)cryptoTransform_).PwdVerifier; } - #endregion + #endregion Encryption #region Deflation Support + /// /// Deflates everything in the input buffers. This will call /// def.deflate() until all bytes from the input buffers @@ -224,31 +241,39 @@ protected void InitializeAESPassword(ZipEntry entry, string rawPassword, /// protected void Deflate() { - while (!deflater_.IsNeedingInput) { + while (!deflater_.IsNeedingInput) + { int deflateCount = deflater_.Deflate(buffer_, 0, buffer_.Length); - if (deflateCount <= 0) { + if (deflateCount <= 0) + { break; } - if (cryptoTransform_ != null) { + if (cryptoTransform_ != null) + { EncryptBlock(buffer_, 0, deflateCount); } baseOutputStream_.Write(buffer_, 0, deflateCount); } - if (!deflater_.IsNeedingInput) { + if (!deflater_.IsNeedingInput) + { throw new SharpZipBaseException("DeflaterOutputStream can't deflate all input?"); } } - #endregion + + #endregion Deflation Support #region Stream Overrides + /// /// Gets value indicating stream can be read from /// - public override bool CanRead { - get { + public override bool CanRead + { + get + { return false; } } @@ -257,8 +282,10 @@ public override bool CanRead { /// Gets a value indicating if seeking is supported for this stream /// This property always returns false ///
- public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return false; } } @@ -266,8 +293,10 @@ public override bool CanSeek { /// /// Get value indicating if this stream supports writing /// - public override bool CanWrite { - get { + public override bool CanWrite + { + get + { return baseOutputStream_.CanWrite; } } @@ -275,8 +304,10 @@ public override bool CanWrite { /// /// Get current length of stream /// - public override long Length { - get { + public override long Length + { + get + { return baseOutputStream_.Length; } } @@ -285,11 +316,14 @@ public override long Length { /// Gets the current position within the stream. ///
/// Any attempt to set position - public override long Position { - get { + public override long Position + { + get + { return baseOutputStream_.Position; } - set { + set + { throw new NotSupportedException("Position property not supported"); } } @@ -356,18 +390,24 @@ public override void Flush() ///
protected override void Dispose(bool disposing) { - if (!isClosed_) { + if (!isClosed_) + { isClosed_ = true; - try { + try + { Finish(); - if (cryptoTransform_ != null) { + if (cryptoTransform_ != null) + { GetAuthCodeIfAES(); cryptoTransform_.Dispose(); cryptoTransform_ = null; } - } finally { - if (IsStreamOwner) { + } + finally + { + if (IsStreamOwner) + { baseOutputStream_.Dispose(); } } @@ -376,7 +416,8 @@ protected override void Dispose(bool disposing) private void GetAuthCodeIfAES() { - if (cryptoTransform_ is ZipAESTransform) { + if (cryptoTransform_ is ZipAESTransform) + { AESAuthCode = ((ZipAESTransform)cryptoTransform_).GetAuthCode(); } } @@ -411,14 +452,16 @@ public override void Write(byte[] buffer, int offset, int count) deflater_.SetInput(buffer, offset, count); Deflate(); } - #endregion + + #endregion Stream Overrides #region Instance Fields + /// /// This buffer is used temporarily to retrieve the bytes from the /// deflater and write them to the underlying output stream. /// - byte[] buffer_; + private byte[] buffer_; /// /// The deflater which is used to deflate the stream. @@ -430,13 +473,15 @@ public override void Write(byte[] buffer, int offset, int count) /// protected Stream baseOutputStream_; - bool isClosed_; - #endregion + private bool isClosed_; + + #endregion Instance Fields #region Static Fields // Static to help ensure that multiple files within a zip will get different random salt private static RandomNumberGenerator _aesRnd = RandomNumberGenerator.Create(); - #endregion + + #endregion Static Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs index cd73fbb15..294091f4d 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs @@ -13,6 +13,7 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams public class InflaterInputBuffer { #region Constructors + /// /// Initialise a new instance of with a default buffer size /// @@ -30,19 +31,23 @@ public InflaterInputBuffer(Stream stream) : this(stream, 4096) public InflaterInputBuffer(Stream stream, int bufferSize) { inputStream = stream; - if (bufferSize < 1024) { + if (bufferSize < 1024) + { bufferSize = 1024; } rawData = new byte[bufferSize]; clearText = rawData; } - #endregion + + #endregion Constructors /// /// Get the length of bytes bytes in the /// - public int RawLength { - get { + public int RawLength + { + get + { return rawLength; } } @@ -51,8 +56,10 @@ public int RawLength { /// Get the contents of the raw data buffer. ///
/// This may contain encrypted data. - public byte[] RawData { - get { + public byte[] RawData + { + get + { return rawData; } } @@ -60,8 +67,10 @@ public byte[] RawData { /// /// Get the number of useable bytes in /// - public int ClearTextLength { - get { + public int ClearTextLength + { + get + { return clearTextLength; } } @@ -69,8 +78,10 @@ public int ClearTextLength { /// /// Get the contents of the clear text buffer. /// - public byte[] ClearText { - get { + public byte[] ClearText + { + get + { return clearText; } } @@ -78,7 +89,8 @@ public byte[] ClearText { /// /// Get/set the number of bytes available /// - public int Available { + public int Available + { get { return available; } set { available = value; } } @@ -89,7 +101,8 @@ public int Available { /// The inflater to set input for. public void SetInflaterInput(Inflater inflater) { - if (available > 0) { + if (available > 0) + { inflater.SetInput(clearText, clearTextLength - available, available); available = 0; } @@ -103,18 +116,23 @@ public void Fill() rawLength = 0; int toRead = rawData.Length; - while (toRead > 0) { + while (toRead > 0) + { int count = inputStream.Read(rawData, rawLength, toRead); - if (count <= 0) { + if (count <= 0) + { break; } rawLength += count; toRead -= count; } - if (cryptoTransform != null) { + if (cryptoTransform != null) + { clearTextLength = cryptoTransform.TransformBlock(rawData, 0, rawLength, clearText, 0); - } else { + } + else + { clearTextLength = rawLength; } @@ -140,17 +158,21 @@ public int ReadRawBuffer(byte[] buffer) /// Returns the number of bytes read. public int ReadRawBuffer(byte[] outBuffer, int offset, int length) { - if (length < 0) { + if (length < 0) + { throw new ArgumentOutOfRangeException(nameof(length)); } int currentOffset = offset; int currentLength = length; - while (currentLength > 0) { - if (available <= 0) { + while (currentLength > 0) + { + if (available <= 0) + { Fill(); - if (available <= 0) { + if (available <= 0) + { return 0; } } @@ -172,17 +194,21 @@ public int ReadRawBuffer(byte[] outBuffer, int offset, int length) /// Returns the number of bytes actually read. public int ReadClearTextBuffer(byte[] outBuffer, int offset, int length) { - if (length < 0) { + if (length < 0) + { throw new ArgumentOutOfRangeException(nameof(length)); } int currentOffset = offset; int currentLength = length; - while (currentLength > 0) { - if (available <= 0) { + while (currentLength > 0) + { + if (available <= 0) + { Fill(); - if (available <= 0) { + if (available <= 0) + { return 0; } } @@ -202,9 +228,11 @@ public int ReadClearTextBuffer(byte[] outBuffer, int offset, int length) /// Returns the byte read. public int ReadLeByte() { - if (available <= 0) { + if (available <= 0) + { Fill(); - if (available <= 0) { + if (available <= 0) + { throw new ZipException("EOF in header"); } } @@ -244,21 +272,29 @@ public long ReadLeLong() /// Get/set the to apply to any data. ///
/// Set this value to null to have no transform applied. - public ICryptoTransform CryptoTransform { - set { + public ICryptoTransform CryptoTransform + { + set + { cryptoTransform = value; - if (cryptoTransform != null) { - if (rawData == clearText) { - if (internalClearText == null) { + if (cryptoTransform != null) + { + if (rawData == clearText) + { + if (internalClearText == null) + { internalClearText = new byte[rawData.Length]; } clearText = internalClearText; } clearTextLength = rawLength; - if (available > 0) { + if (available > 0) + { cryptoTransform.TransformBlock(rawData, rawLength - available, available, clearText, rawLength - available); } - } else { + } + else + { clearText = rawData; clearTextLength = rawLength; } @@ -266,18 +302,20 @@ public ICryptoTransform CryptoTransform { } #region Instance Fields - int rawLength; - byte[] rawData; - int clearTextLength; - byte[] clearText; - byte[] internalClearText; + private int rawLength; + private byte[] rawData; - int available; + private int clearTextLength; + private byte[] clearText; + private byte[] internalClearText; - ICryptoTransform cryptoTransform; - Stream inputStream; - #endregion + private int available; + + private ICryptoTransform cryptoTransform; + private Stream inputStream; + + #endregion Instance Fields } /// @@ -292,6 +330,7 @@ public ICryptoTransform CryptoTransform { public class InflaterInputStream : Stream { #region Constructors + /// /// Create an InflaterInputStream with the default decompressor /// and a default buffer size of 4KB. @@ -334,15 +373,18 @@ public InflaterInputStream(Stream baseInputStream, Inflater inf) /// public InflaterInputStream(Stream baseInputStream, Inflater inflater, int bufferSize) { - if (baseInputStream == null) { + if (baseInputStream == null) + { throw new ArgumentNullException(nameof(baseInputStream)); } - if (inflater == null) { + if (inflater == null) + { throw new ArgumentNullException(nameof(inflater)); } - if (bufferSize <= 0) { + if (bufferSize <= 0) + { throw new ArgumentOutOfRangeException(nameof(bufferSize)); } @@ -352,7 +394,7 @@ public InflaterInputStream(Stream baseInputStream, Inflater inflater, int buffer inputBuffer = new InflaterInputBuffer(baseInputStream, bufferSize); } - #endregion + #endregion Constructors /// /// Gets or sets a flag indicating ownership of underlying stream. @@ -368,7 +410,7 @@ public InflaterInputStream(Stream baseInputStream, Inflater inflater, int buffer /// Number of bytes to skip /// /// - /// The number of bytes skipped, zero if the end of + /// The number of bytes skipped, zero if the end of /// stream has been reached /// /// @@ -376,17 +418,22 @@ public InflaterInputStream(Stream baseInputStream, Inflater inflater, int buffer /// public long Skip(long count) { - if (count <= 0) { + if (count <= 0) + { throw new ArgumentOutOfRangeException(nameof(count)); } // v0.80 Skip by seeking if underlying stream supports it... - if (baseInputStream.CanSeek) { + if (baseInputStream.CanSeek) + { baseInputStream.Seek(count, SeekOrigin.Current); return count; - } else { + } + else + { int length = 2048; - if (count < length) { + if (count < length) + { length = (int)count; } @@ -394,8 +441,10 @@ public long Skip(long count) int readCount = 1; long toSkip = count; - while ((toSkip > 0) && (readCount > 0)) { - if (toSkip < length) { + while ((toSkip > 0) && (readCount > 0)) + { + if (toSkip < length) + { length = (int)toSkip; } @@ -409,7 +458,7 @@ public long Skip(long count) /// /// Clear any cryptographic state. - /// + /// protected void StopDecrypting() { inputBuffer.CryptoTransform = null; @@ -419,8 +468,10 @@ protected void StopDecrypting() /// Returns 0 once the end of the stream (EOF) has been reached. /// Otherwise returns 1. /// - public virtual int Available { - get { + public virtual int Available + { + get + { return inf.IsFinished ? 0 : 1; } } @@ -434,9 +485,11 @@ public virtual int Available { protected void Fill() { // Protect against redundant calls - if (inputBuffer.Available <= 0) { + if (inputBuffer.Available <= 0) + { inputBuffer.Fill(); - if (inputBuffer.Available <= 0) { + if (inputBuffer.Available <= 0) + { throw new SharpZipBaseException("Unexpected EOF"); } } @@ -444,11 +497,14 @@ protected void Fill() } #region Stream Overrides + /// /// Gets a value indicating whether the current stream supports reading /// - public override bool CanRead { - get { + public override bool CanRead + { + get + { return baseInputStream.CanRead; } } @@ -456,8 +512,10 @@ public override bool CanRead { /// /// Gets a value of false indicating seeking is not supported for this stream. /// - public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return false; } } @@ -465,8 +523,10 @@ public override bool CanSeek { /// /// Gets a value of false indicating that this stream is not writeable. /// - public override bool CanWrite { - get { + public override bool CanWrite + { + get + { return false; } } @@ -474,10 +534,12 @@ public override bool CanWrite { /// /// A value representing the length of the stream in bytes. /// - public override long Length { - get { + public override long Length + { + get + { //return inputBuffer.RawLength; - throw new NotSupportedException("InflaterInputStream Length is not supported"); + throw new NotSupportedException("InflaterInputStream Length is not supported"); } } @@ -486,11 +548,14 @@ public override long Length { /// Throws a NotSupportedException when attempting to set the position /// /// Attempting to set the position - public override long Position { - get { + public override long Position + { + get + { return baseInputStream.Position; } - set { + set + { throw new NotSupportedException("InflaterInputStream Position not supported"); } } @@ -557,9 +622,11 @@ public override void WriteByte(byte value) /// protected override void Dispose(bool disposing) { - if (!isClosed) { + if (!isClosed) + { isClosed = true; - if (IsStreamOwner) { + if (IsStreamOwner) + { baseInputStream.Dispose(); } } @@ -583,31 +650,39 @@ protected override void Dispose(bool disposing) /// public override int Read(byte[] buffer, int offset, int count) { - if (inf.IsNeedingDictionary) { + if (inf.IsNeedingDictionary) + { throw new SharpZipBaseException("Need a dictionary"); } int remainingBytes = count; - while (true) { + while (true) + { int bytesRead = inf.Inflate(buffer, offset, remainingBytes); offset += bytesRead; remainingBytes -= bytesRead; - if (remainingBytes == 0 || inf.IsFinished) { + if (remainingBytes == 0 || inf.IsFinished) + { break; } - if (inf.IsNeedingInput) { + if (inf.IsNeedingInput) + { Fill(); - } else if (bytesRead == 0) { + } + else if (bytesRead == 0) + { throw new ZipException("Invalid input data"); } } return count - remainingBytes; } - #endregion + + #endregion Stream Overrides #region Instance Fields + /// /// Decompressor for this stream /// @@ -631,7 +706,8 @@ public override int Read(byte[] buffer, int offset, int count) /// /// Flag indicating wether this instance has been closed or not. /// - bool isClosed; - #endregion + private bool isClosed; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs index cd31784c0..d8241c18c 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs @@ -11,15 +11,19 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams public class OutputWindow { #region Constants - const int WindowSize = 1 << 15; - const int WindowMask = WindowSize - 1; - #endregion + + private const int WindowSize = 1 << 15; + private const int WindowMask = WindowSize - 1; + + #endregion Constants #region Instance Fields - byte[] window = new byte[WindowSize]; //The window is 2^15 bytes - int windowEnd; - int windowFilled; - #endregion + + private byte[] window = new byte[WindowSize]; //The window is 2^15 bytes + private int windowEnd; + private int windowFilled; + + #endregion Instance Fields /// /// Write a byte to this output window @@ -30,17 +34,18 @@ public class OutputWindow /// public void Write(int value) { - if (windowFilled++ == WindowSize) { + if (windowFilled++ == WindowSize) + { throw new InvalidOperationException("Window full"); } window[windowEnd++] = (byte)value; windowEnd &= WindowMask; } - private void SlowRepeat(int repStart, int length, int distance) { - while (length-- > 0) { + while (length-- > 0) + { window[windowEnd++] = window[repStart++]; windowEnd &= WindowMask; repStart &= WindowMask; @@ -57,23 +62,31 @@ private void SlowRepeat(int repStart, int length, int distance) /// public void Repeat(int length, int distance) { - if ((windowFilled += length) > WindowSize) { + if ((windowFilled += length) > WindowSize) + { throw new InvalidOperationException("Window full"); } int repStart = (windowEnd - distance) & WindowMask; int border = WindowSize - length; - if ((repStart <= border) && (windowEnd < border)) { - if (length <= distance) { + if ((repStart <= border) && (windowEnd < border)) + { + if (length <= distance) + { System.Array.Copy(window, repStart, window, windowEnd, length); windowEnd += length; - } else { + } + else + { // We have to copy manually, since the repeat pattern overlaps. - while (length-- > 0) { + while (length-- > 0) + { window[windowEnd++] = window[repStart++]; } } - } else { + } + else + { SlowRepeat(repStart, length, distance); } } @@ -90,12 +103,16 @@ public int CopyStored(StreamManipulator input, int length) int copied; int tailLen = WindowSize - windowEnd; - if (length > tailLen) { + if (length > tailLen) + { copied = input.CopyBytes(window, windowEnd, tailLen); - if (copied == tailLen) { + if (copied == tailLen) + { copied += input.CopyBytes(window, 0, length - tailLen); } - } else { + } + else + { copied = input.CopyBytes(window, windowEnd, length); } @@ -115,15 +132,18 @@ public int CopyStored(StreamManipulator input, int length) /// public void CopyDict(byte[] dictionary, int offset, int length) { - if (dictionary == null) { + if (dictionary == null) + { throw new ArgumentNullException(nameof(dictionary)); } - if (windowFilled > 0) { + if (windowFilled > 0) + { throw new InvalidOperationException(); } - if (length > WindowSize) { + if (length > WindowSize) + { offset += length - WindowSize; length = WindowSize; } @@ -162,23 +182,28 @@ public int GetAvailable() public int CopyOutput(byte[] output, int offset, int len) { int copyEnd = windowEnd; - if (len > windowFilled) { + if (len > windowFilled) + { len = windowFilled; - } else { + } + else + { copyEnd = (windowEnd - windowFilled + len) & WindowMask; } int copied = len; int tailLen = len - copyEnd; - if (tailLen > 0) { + if (tailLen > 0) + { System.Array.Copy(window, WindowSize - tailLen, output, offset, tailLen); offset += tailLen; len = copyEnd; } System.Array.Copy(window, copyEnd - len, output, offset, len); windowFilled -= copied; - if (windowFilled < 0) { + if (windowFilled < 0) + { throw new InvalidOperationException(); } return copied; diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs index f3850f5d0..aff6a9c6c 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs @@ -30,8 +30,10 @@ public class StreamManipulator /// public int PeekBits(int bitCount) { - if (bitsInBuffer_ < bitCount) { - if (windowStart_ == windowEnd_) { + if (bitsInBuffer_ < bitCount) + { + if (windowStart_ == windowEnd_) + { return -1; // ok } buffer_ |= (uint)((window_[windowStart_++] & 0xff | @@ -42,7 +44,7 @@ public int PeekBits(int bitCount) } /// - /// Tries to grab the next bits from the input and + /// Tries to grab the next bits from the input and /// sets to the value, adding . /// /// true if enough bits could be read, otherwise false @@ -59,8 +61,8 @@ public bool TryGetBits(int bitCount, ref int output, int outputOffset = 0) } /// - /// Tries to grab the next bits from the input and - /// sets to the value, adding . + /// Tries to grab the next bits from the input and + /// sets of to the value. /// /// true if enough bits could be read, otherwise false public bool TryGetBits(int bitCount, ref byte[] array, int index) @@ -98,7 +100,8 @@ public void DropBits(int bitCount) public int GetBits(int bitCount) { int bits = PeekBits(bitCount); - if (bits >= 0) { + if (bits >= 0) + { DropBits(bitCount); } return bits; @@ -111,8 +114,10 @@ public int GetBits(int bitCount) /// /// the number of bits available. /// - public int AvailableBits { - get { + public int AvailableBits + { + get + { return bitsInBuffer_; } } @@ -123,8 +128,10 @@ public int AvailableBits { /// /// The number of bytes available. /// - public int AvailableBytes { - get { + public int AvailableBytes + { + get + { return windowEnd_ - windowStart_ + (bitsInBuffer_ >> 3); } } @@ -141,8 +148,10 @@ public void SkipToByteBoundary() /// /// Returns true when SetInput can be called /// - public bool IsNeedingInput { - get { + public bool IsNeedingInput + { + get + { return windowStart_ == windowEnd_; } } @@ -173,17 +182,20 @@ public bool IsNeedingInput { /// public int CopyBytes(byte[] output, int offset, int length) { - if (length < 0) { + if (length < 0) + { throw new ArgumentOutOfRangeException(nameof(length)); } - if ((bitsInBuffer_ & 7) != 0) { + if ((bitsInBuffer_ & 7) != 0) + { // bits_in_buffer may only be 0 or a multiple of 8 throw new InvalidOperationException("Bit buffer is not byte aligned!"); } int count = 0; - while ((bitsInBuffer_ > 0) && (length > 0)) { + while ((bitsInBuffer_ > 0) && (length > 0)) + { output[offset++] = (byte)buffer_; buffer_ >>= 8; bitsInBuffer_ -= 8; @@ -191,18 +203,21 @@ public int CopyBytes(byte[] output, int offset, int length) count++; } - if (length == 0) { + if (length == 0) + { return count; } int avail = windowEnd_ - windowStart_; - if (length > avail) { + if (length > avail) + { length = avail; } System.Array.Copy(window_, windowStart_, output, offset, length); windowStart_ += length; - if (((windowStart_ - windowEnd_) & 1) != 0) { + if (((windowStart_ - windowEnd_) & 1) != 0) + { // We always want an even number of bytes in input, see peekBits buffer_ = (uint)(window_[windowStart_++] & 0xff); bitsInBuffer_ = 8; @@ -228,19 +243,23 @@ public void Reset() /// number of bytes of input to add. public void SetInput(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset), "Cannot be negative"); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count), "Cannot be negative"); } - if (windowStart_ < windowEnd_) { + if (windowStart_ < windowEnd_) + { throw new InvalidOperationException("Old input was not completely processed"); } @@ -248,11 +267,13 @@ public void SetInput(byte[] buffer, int offset, int count) // We want to throw an ArrayIndexOutOfBoundsException early. // Note the check also handles integer wrap around. - if ((offset > end) || (end > buffer.Length)) { + if ((offset > end) || (end > buffer.Length)) + { throw new ArgumentOutOfRangeException(nameof(count)); } - if ((count & 1) != 0) { + if ((count & 1) != 0) + { // We always want an even number of bytes in input, see PeekBits buffer_ |= (uint)((buffer[offset++] & 0xff) << bitsInBuffer_); bitsInBuffer_ += 8; @@ -264,12 +285,14 @@ public void SetInput(byte[] buffer, int offset, int count) } #region Instance Fields + private byte[] window_; private int windowStart_; private int windowEnd_; private uint buffer_; private int bitsInBuffer_; - #endregion + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs b/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs index c58b4ccf2..c4534fb6a 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs @@ -1,7 +1,7 @@ -using System; -using System.IO; using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Zip.Compression; +using System; +using System.IO; using static ICSharpCode.SharpZipLib.Zip.Compression.Deflater; namespace ICSharpCode.SharpZipLib.Zip @@ -52,7 +52,8 @@ public bool OnDirectoryFailure(string directory, Exception e) bool result = false; DirectoryFailureHandler handler = DirectoryFailure; - if (handler != null) { + if (handler != null) + { var args = new ScanFailureEventArgs(directory, e); handler(this, args); result = args.ContinueRunning; @@ -71,7 +72,8 @@ public bool OnFileFailure(string file, Exception e) FileFailureHandler handler = FileFailure; bool result = (handler != null); - if (result) { + if (result) + { var args = new ScanFailureEventArgs(file, e); handler(this, args); result = args.ContinueRunning; @@ -89,7 +91,8 @@ public bool OnProcessFile(string file) bool result = true; ProcessFileHandler handler = ProcessFile; - if (handler != null) { + if (handler != null) + { var args = new ScanEventArgs(file); handler(this, args); result = args.ContinueRunning; @@ -106,7 +109,8 @@ public bool OnCompletedFile(string file) { bool result = true; CompletedFileHandler handler = CompletedFile; - if (handler != null) { + if (handler != null) + { var args = new ScanEventArgs(file); handler(this, args); result = args.ContinueRunning; @@ -124,7 +128,8 @@ public bool OnProcessDirectory(string directory, bool hasMatchingFiles) { bool result = true; EventHandler handler = ProcessDirectory; - if (handler != null) { + if (handler != null) + { var args = new DirectoryEventArgs(directory, hasMatchingFiles); handler(this, args); result = args.ContinueRunning; @@ -138,14 +143,17 @@ public bool OnProcessDirectory(string directory, bool hasMatchingFiles) /// The minimum period of time between events. /// /// The default interval is three seconds. - public TimeSpan ProgressInterval { + public TimeSpan ProgressInterval + { get { return progressInterval_; } set { progressInterval_ = value; } } #region Instance Fields - TimeSpan progressInterval_ = TimeSpan.FromSeconds(3); - #endregion + + private TimeSpan progressInterval_ = TimeSpan.FromSeconds(3); + + #endregion Instance Fields } /// @@ -154,6 +162,7 @@ public TimeSpan ProgressInterval { public class FastZip { #region Enumerations + /// /// Defines the desired handling when overwriting files during extraction. /// @@ -163,19 +172,22 @@ public enum Overwrite /// Prompt the user to confirm overwriting /// Prompt, + /// /// Never overwrite files. /// Never, + /// /// Always overwrite files. /// Always } - #endregion + #endregion Enumerations #region Constructors + /// /// Initialise a default instance of . /// @@ -191,13 +203,16 @@ public FastZip(FastZipEvents events) { events_ = events; } - #endregion + + #endregion Constructors #region Properties + /// /// Get/set a value indicating wether empty directories should be created. /// - public bool CreateEmptyDirectories { + public bool CreateEmptyDirectories + { get { return createEmptyDirectories_; } set { createEmptyDirectories_ = value; } } @@ -205,7 +220,8 @@ public bool CreateEmptyDirectories { /// /// Get / set the password value. /// - public string Password { + public string Password + { get { return password_; } set { password_ = value; } } @@ -214,9 +230,11 @@ public string Password { /// Get or set the active when creating Zip files. /// /// - public INameTransform NameTransform { + public INameTransform NameTransform + { get { return entryFactory_.NameTransform; } - set { + set + { entryFactory_.NameTransform = value; } } @@ -224,12 +242,17 @@ public INameTransform NameTransform { /// /// Get or set the active when creating Zip files. /// - public IEntryFactory EntryFactory { + public IEntryFactory EntryFactory + { get { return entryFactory_; } - set { - if (value == null) { + set + { + if (value == null) + { entryFactory_ = new ZipEntryFactory(); - } else { + } + else + { entryFactory_ = value; } } @@ -246,21 +269,25 @@ public IEntryFactory EntryFactory { /// NOTE: Setting the size for entries before they are added is the best solution! /// By default the EntryFactory used by FastZip will set fhe file size. /// - public UseZip64 UseZip64 { + public UseZip64 UseZip64 + { get { return useZip64_; } set { useZip64_ = value; } } /// - /// Get/set a value indicating wether file dates and times should + /// Get/set a value indicating wether file dates and times should /// be restored when extracting files from an archive. /// /// The default value is false. - public bool RestoreDateTimeOnExtract { - get { + public bool RestoreDateTimeOnExtract + { + get + { return restoreDateTimeOnExtract_; } - set { + set + { restoreDateTimeOnExtract_ = value; } } @@ -269,29 +296,35 @@ public bool RestoreDateTimeOnExtract { /// Get/set a value indicating whether file attributes should /// be restored during extract operations /// - public bool RestoreAttributesOnExtract { + public bool RestoreAttributesOnExtract + { get { return restoreAttributesOnExtract_; } set { restoreAttributesOnExtract_ = value; } } - /// - /// Get/set the Compression Level that will be used - /// when creating the zip - /// - public Deflater.CompressionLevel CompressionLevel{ - get { return compressionLevel_; } - set { compressionLevel_ = value; } - } - #endregion + /// + /// Get/set the Compression Level that will be used + /// when creating the zip + /// + public Deflater.CompressionLevel CompressionLevel + { + get { return compressionLevel_; } + set { compressionLevel_ = value; } + } + + #endregion Properties #region Delegates + /// /// Delegate called when confirming overwriting of files. /// public delegate bool ConfirmOverwriteDelegate(string fileName); - #endregion + + #endregion Delegates #region CreateZip + /// /// Create a zip file. /// @@ -332,27 +365,32 @@ public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, NameTransform = new ZipNameTransform(sourceDirectory); sourceDirectory_ = sourceDirectory; - using (outputStream_ = new ZipOutputStream(outputStream)) { + using (outputStream_ = new ZipOutputStream(outputStream)) + { + outputStream_.SetLevel((int)CompressionLevel); - outputStream_.SetLevel((int)CompressionLevel); - - if (password_ != null) { + if (password_ != null) + { outputStream_.Password = password_; } outputStream_.UseZip64 = UseZip64; var scanner = new FileSystemScanner(fileFilter, directoryFilter); scanner.ProcessFile += ProcessFile; - if (this.CreateEmptyDirectories) { + if (this.CreateEmptyDirectories) + { scanner.ProcessDirectory += ProcessDirectory; } - if (events_ != null) { - if (events_.FileFailure != null) { + if (events_ != null) + { + if (events_.FileFailure != null) + { scanner.FileFailure += events_.FileFailure; } - if (events_.DirectoryFailure != null) { + if (events_.DirectoryFailure != null) + { scanner.DirectoryFailure += events_.DirectoryFailure; } } @@ -361,9 +399,10 @@ public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, } } - #endregion + #endregion CreateZip #region ExtractZip + /// /// Extract the contents of a zip file. /// @@ -411,7 +450,8 @@ public void ExtractZip(Stream inputStream, string targetDirectory, string fileFilter, string directoryFilter, bool restoreDateTime, bool isStreamOwner, bool allowParentTraversal = false) { - if ((overwrite == Overwrite.Prompt) && (confirmDelegate == null)) { + if ((overwrite == Overwrite.Prompt) && (confirmDelegate == null)) + { throw new ArgumentNullException(nameof(confirmDelegate)); } @@ -424,42 +464,57 @@ public void ExtractZip(Stream inputStream, string targetDirectory, directoryFilter_ = new NameFilter(directoryFilter); restoreDateTimeOnExtract_ = restoreDateTime; - using (zipFile_ = new ZipFile(inputStream)) { - - if (password_ != null) { + using (zipFile_ = new ZipFile(inputStream)) + { + if (password_ != null) + { zipFile_.Password = password_; } zipFile_.IsStreamOwner = isStreamOwner; System.Collections.IEnumerator enumerator = zipFile_.GetEnumerator(); - while (continueRunning_ && enumerator.MoveNext()) { + while (continueRunning_ && enumerator.MoveNext()) + { var entry = (ZipEntry)enumerator.Current; - if (entry.IsFile) { + if (entry.IsFile) + { // TODO Path.GetDirectory can fail here on invalid characters. - if (directoryFilter_.IsMatch(Path.GetDirectoryName(entry.Name)) && fileFilter_.IsMatch(entry.Name)) { + if (directoryFilter_.IsMatch(Path.GetDirectoryName(entry.Name)) && fileFilter_.IsMatch(entry.Name)) + { ExtractEntry(entry); } - } else if (entry.IsDirectory) { - if (directoryFilter_.IsMatch(entry.Name) && CreateEmptyDirectories) { + } + else if (entry.IsDirectory) + { + if (directoryFilter_.IsMatch(entry.Name) && CreateEmptyDirectories) + { ExtractEntry(entry); } - } else { + } + else + { // Do nothing for volume labels etc... } } } } - #endregion + + #endregion ExtractZip #region Internal Processing - void ProcessDirectory(object sender, DirectoryEventArgs e) + + private void ProcessDirectory(object sender, DirectoryEventArgs e) { - if (!e.HasMatchingFiles && CreateEmptyDirectories) { - if (events_ != null) { + if (!e.HasMatchingFiles && CreateEmptyDirectories) + { + if (events_ != null) + { events_.OnProcessDirectory(e.Name, e.HasMatchingFiles); } - if (e.ContinueRunning) { - if (e.Name != sourceDirectory_) { + if (e.ContinueRunning) + { + if (e.Name != sourceDirectory_) + { ZipEntry entry = entryFactory_.MakeDirectoryEntry(e.Name); outputStream_.PutNextEntry(entry); } @@ -467,26 +522,35 @@ void ProcessDirectory(object sender, DirectoryEventArgs e) } } - void ProcessFile(object sender, ScanEventArgs e) + private void ProcessFile(object sender, ScanEventArgs e) { - if ((events_ != null) && (events_.ProcessFile != null)) { + if ((events_ != null) && (events_.ProcessFile != null)) + { events_.ProcessFile(sender, e); } - if (e.ContinueRunning) { - try { - // The open below is equivalent to OpenRead which gaurantees that if opened the + if (e.ContinueRunning) + { + try + { + // The open below is equivalent to OpenRead which gaurantees that if opened the // file will not be changed by subsequent openers, but precludes opening in some cases // were it could succeed. ie the open may fail as its already open for writing and the share mode should reflect that. - using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read)) { + using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read)) + { ZipEntry entry = entryFactory_.MakeFileEntry(e.Name); outputStream_.PutNextEntry(entry); AddFileContents(e.Name, stream); } - } catch (Exception ex) { - if (events_ != null) { + } + catch (Exception ex) + { + if (events_ != null) + { continueRunning_ = events_.OnFileFailure(e.Name, ex); - } else { + } + else + { continueRunning_ = false; throw; } @@ -494,78 +558,106 @@ void ProcessFile(object sender, ScanEventArgs e) } } - void AddFileContents(string name, Stream stream) + private void AddFileContents(string name, Stream stream) { - if (stream == null) { + if (stream == null) + { throw new ArgumentNullException(nameof(stream)); } - if (buffer_ == null) { + if (buffer_ == null) + { buffer_ = new byte[4096]; } - if ((events_ != null) && (events_.Progress != null)) { + if ((events_ != null) && (events_.Progress != null)) + { StreamUtils.Copy(stream, outputStream_, buffer_, events_.Progress, events_.ProgressInterval, this, name); - } else { + } + else + { StreamUtils.Copy(stream, outputStream_, buffer_); } - if (events_ != null) { + if (events_ != null) + { continueRunning_ = events_.OnCompletedFile(name); } } - void ExtractFileEntry(ZipEntry entry, string targetName) + private void ExtractFileEntry(ZipEntry entry, string targetName) { bool proceed = true; - if (overwrite_ != Overwrite.Always) { - if (File.Exists(targetName)) { - if ((overwrite_ == Overwrite.Prompt) && (confirmDelegate_ != null)) { + if (overwrite_ != Overwrite.Always) + { + if (File.Exists(targetName)) + { + if ((overwrite_ == Overwrite.Prompt) && (confirmDelegate_ != null)) + { proceed = confirmDelegate_(targetName); - } else { + } + else + { proceed = false; } } } - if (proceed) { - if (events_ != null) { + if (proceed) + { + if (events_ != null) + { continueRunning_ = events_.OnProcessFile(entry.Name); } - if (continueRunning_) { - try { - using (FileStream outputStream = File.Create(targetName)) { - if (buffer_ == null) { + if (continueRunning_) + { + try + { + using (FileStream outputStream = File.Create(targetName)) + { + if (buffer_ == null) + { buffer_ = new byte[4096]; } - if ((events_ != null) && (events_.Progress != null)) { + if ((events_ != null) && (events_.Progress != null)) + { StreamUtils.Copy(zipFile_.GetInputStream(entry), outputStream, buffer_, events_.Progress, events_.ProgressInterval, this, entry.Name, entry.Size); - } else { + } + else + { StreamUtils.Copy(zipFile_.GetInputStream(entry), outputStream, buffer_); } - if (events_ != null) { + if (events_ != null) + { continueRunning_ = events_.OnCompletedFile(entry.Name); } } - if (restoreDateTimeOnExtract_) { + if (restoreDateTimeOnExtract_) + { File.SetLastWriteTime(targetName, entry.DateTime); } - if (RestoreAttributesOnExtract && entry.IsDOSEntry && (entry.ExternalFileAttributes != -1)) { + if (RestoreAttributesOnExtract && entry.IsDOSEntry && (entry.ExternalFileAttributes != -1)) + { var fileAttributes = (FileAttributes)entry.ExternalFileAttributes; // TODO: FastZip - Setting of other file attributes on extraction is a little trickier. fileAttributes &= (FileAttributes.Archive | FileAttributes.Normal | FileAttributes.ReadOnly | FileAttributes.Hidden); File.SetAttributes(targetName, fileAttributes); } - } catch (Exception ex) { - if (events_ != null) { + } + catch (Exception ex) + { + if (events_ != null) + { continueRunning_ = events_.OnFileFailure(targetName, ex); - } else { + } + else + { continueRunning_ = false; throw; } @@ -574,15 +666,19 @@ void ExtractFileEntry(ZipEntry entry, string targetName) } } - void ExtractEntry(ZipEntry entry) + private void ExtractEntry(ZipEntry entry) { bool doExtraction = entry.IsCompressionMethodSupported(); string targetName = entry.Name; - if (doExtraction) { - if (entry.IsFile) { + if (doExtraction) + { + if (entry.IsFile) + { targetName = extractNameTransform_.TransformFile(targetName); - } else if (entry.IsDirectory) { + } + else if (entry.IsDirectory) + { targetName = extractNameTransform_.TransformDirectory(targetName); } @@ -593,27 +689,42 @@ void ExtractEntry(ZipEntry entry) string dirName = null; - if (doExtraction) { - if (entry.IsDirectory) { + if (doExtraction) + { + if (entry.IsDirectory) + { dirName = targetName; - } else { + } + else + { dirName = Path.GetDirectoryName(Path.GetFullPath(targetName)); } } - if (doExtraction && !Directory.Exists(dirName)) { - if (!entry.IsDirectory || CreateEmptyDirectories) { - try { + if (doExtraction && !Directory.Exists(dirName)) + { + if (!entry.IsDirectory || CreateEmptyDirectories) + { + try + { Directory.CreateDirectory(dirName); - } catch (Exception ex) { + } + catch (Exception ex) + { doExtraction = false; - if (events_ != null) { - if (entry.IsDirectory) { + if (events_ != null) + { + if (entry.IsDirectory) + { continueRunning_ = events_.OnDirectoryFailure(targetName, ex); - } else { + } + else + { continueRunning_ = events_.OnFileFailure(targetName, ex); } - } else { + } + else + { continueRunning_ = false; throw; } @@ -621,45 +732,48 @@ void ExtractEntry(ZipEntry entry) } } - if (doExtraction && entry.IsFile) { + if (doExtraction && entry.IsFile) + { ExtractFileEntry(entry, targetName); } } - static int MakeExternalAttributes(FileInfo info) + private static int MakeExternalAttributes(FileInfo info) { return (int)info.Attributes; } - static bool NameIsValid(string name) + private static bool NameIsValid(string name) { return !string.IsNullOrEmpty(name) && (name.IndexOfAny(Path.GetInvalidPathChars()) < 0); } - #endregion + + #endregion Internal Processing #region Instance Fields - bool continueRunning_; - byte[] buffer_; - ZipOutputStream outputStream_; - ZipFile zipFile_; - string sourceDirectory_; - NameFilter fileFilter_; - NameFilter directoryFilter_; - Overwrite overwrite_; - ConfirmOverwriteDelegate confirmDelegate_; - - bool restoreDateTimeOnExtract_; - bool restoreAttributesOnExtract_; - bool createEmptyDirectories_; - FastZipEvents events_; - IEntryFactory entryFactory_ = new ZipEntryFactory(); - INameTransform extractNameTransform_; - UseZip64 useZip64_ = UseZip64.Dynamic; - CompressionLevel compressionLevel_ = CompressionLevel.DEFAULT_COMPRESSION; - - string password_; - - #endregion + + private bool continueRunning_; + private byte[] buffer_; + private ZipOutputStream outputStream_; + private ZipFile zipFile_; + private string sourceDirectory_; + private NameFilter fileFilter_; + private NameFilter directoryFilter_; + private Overwrite overwrite_; + private ConfirmOverwriteDelegate confirmDelegate_; + + private bool restoreDateTimeOnExtract_; + private bool restoreAttributesOnExtract_; + private bool createEmptyDirectories_; + private FastZipEvents events_; + private IEntryFactory entryFactory_ = new ZipEntryFactory(); + private INameTransform extractNameTransform_; + private UseZip64 useZip64_ = UseZip64.Dynamic; + private CompressionLevel compressionLevel_ = CompressionLevel.DEFAULT_COMPRESSION; + + private string password_; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs b/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs index 5ae841527..75d97ff19 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs @@ -1,7 +1,7 @@ +using ICSharpCode.SharpZipLib.Core; using System; using System.IO; using System.Text; -using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.Zip { @@ -14,18 +14,18 @@ public class WindowsNameTransform : INameTransform /// The maximum windows path name permitted. /// /// This may not valid for all windows systems - CE?, etc but I cant find the equivalent in the CLR. - const int MaxPath = 260; + private const int MaxPath = 260; - string _baseDirectory; - bool _trimIncomingPaths; - char _replacementChar = '_'; + private string _baseDirectory; + private bool _trimIncomingPaths; + private char _replacementChar = '_'; private bool _allowParentTraversal; /// /// In this case we need Windows' invalid path characters. /// Path.GetInvalidPathChars() only returns a subset invalid on all platforms. /// - static readonly char[] InvalidEntryChars = new char[] { + private static readonly char[] InvalidEntryChars = new char[] { '"', '<', '>', '|', '\0', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', @@ -57,10 +57,13 @@ public WindowsNameTransform() /// /// Gets or sets a value containing the target directory to prefix values with. /// - public string BaseDirectory { + public string BaseDirectory + { get { return _baseDirectory; } - set { - if (value == null) { + set + { + if (value == null) + { throw new ArgumentNullException(nameof(value)); } @@ -80,7 +83,8 @@ public bool AllowParentTraversal /// /// Gets or sets a value indicating wether paths on incoming values should be removed. /// - public bool TrimIncomingPaths { + public bool TrimIncomingPaths + { get { return _trimIncomingPaths; } set { _trimIncomingPaths = value; } } @@ -93,11 +97,15 @@ public bool TrimIncomingPaths { public string TransformDirectory(string name) { name = TransformFile(name); - if (name.Length > 0) { - while (name.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) { + if (name.Length > 0) + { + while (name.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) + { name = name.Remove(name.Length - 1, 1); } - } else { + } + else + { throw new InvalidNameException("Cannot have an empty directory name"); } return name; @@ -110,24 +118,29 @@ public string TransformDirectory(string name) /// The transformed name. public string TransformFile(string name) { - if (name != null) { + if (name != null) + { name = MakeValidName(name, _replacementChar); - if (_trimIncomingPaths) { + if (_trimIncomingPaths) + { name = Path.GetFileName(name); } // This may exceed windows length restrictions. // Combine will throw a PathTooLongException in that case. - if (_baseDirectory != null) { + if (_baseDirectory != null) + { name = Path.Combine(_baseDirectory, name); - if(!_allowParentTraversal && !Path.GetFullPath(name).StartsWith(_baseDirectory, StringComparison.InvariantCultureIgnoreCase)) + if (!_allowParentTraversal && !Path.GetFullPath(name).StartsWith(_baseDirectory, StringComparison.InvariantCultureIgnoreCase)) { throw new InvalidNameException("Parent traversal in paths is not allowed"); } } - } else { + } + else + { name = string.Empty; } return name; @@ -158,40 +171,49 @@ public static bool IsValidName(string name) /// Returns a valid name public static string MakeValidName(string name, char replacement) { - if (name == null) { + if (name == null) + { throw new ArgumentNullException(nameof(name)); } name = WindowsPathUtils.DropPathRoot(name.Replace("/", Path.DirectorySeparatorChar.ToString())); // Drop any leading slashes. - while ((name.Length > 0) && (name[0] == Path.DirectorySeparatorChar)) { + while ((name.Length > 0) && (name[0] == Path.DirectorySeparatorChar)) + { name = name.Remove(0, 1); } // Drop any trailing slashes. - while ((name.Length > 0) && (name[name.Length - 1] == Path.DirectorySeparatorChar)) { + while ((name.Length > 0) && (name[name.Length - 1] == Path.DirectorySeparatorChar)) + { name = name.Remove(name.Length - 1, 1); } // Convert consecutive \\ characters to \ int index = name.IndexOf(string.Format("{0}{0}", Path.DirectorySeparatorChar), StringComparison.Ordinal); - while (index >= 0) { + while (index >= 0) + { name = name.Remove(index, 1); index = name.IndexOf(string.Format("{0}{0}", Path.DirectorySeparatorChar), StringComparison.Ordinal); } // Convert any invalid characters using the replacement one. index = name.IndexOfAny(InvalidEntryChars); - if (index >= 0) { + if (index >= 0) + { var builder = new StringBuilder(name); - while (index >= 0) { + while (index >= 0) + { builder[index] = replacement; - if (index >= name.Length) { + if (index >= name.Length) + { index = -1; - } else { + } + else + { index = name.IndexOfAny(InvalidEntryChars, index + 1); } } @@ -200,7 +222,8 @@ public static string MakeValidName(string name, char replacement) // Check for names greater than MaxPath characters. // TODO: Were is CLR version of MaxPath defined? Can't find it in Environment. - if (name.Length > MaxPath) { + if (name.Length > MaxPath) + { throw new PathTooLongException(); } @@ -210,16 +233,21 @@ public static string MakeValidName(string name, char replacement) /// /// Gets or set the character to replace invalid characters during transformations. /// - public char Replacement { + public char Replacement + { get { return _replacementChar; } - set { - for (int i = 0; i < InvalidEntryChars.Length; ++i) { - if (InvalidEntryChars[i] == value) { + set + { + for (int i = 0; i < InvalidEntryChars.Length; ++i) + { + if (InvalidEntryChars[i] == value) + { throw new ArgumentException("invalid path character"); } } - if ((value == Path.DirectorySeparatorChar) || (value == Path.AltDirectorySeparatorChar)) { + if ((value == Path.DirectorySeparatorChar) || (value == Path.AltDirectorySeparatorChar)) + { throw new ArgumentException("invalid replacement character"); } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs index 1fbe848e5..437213492 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs @@ -1,7 +1,4 @@ using System; -using System.Globalization; -using System.Text; -using System.Threading; namespace ICSharpCode.SharpZipLib.Zip { @@ -17,10 +14,12 @@ public enum UseZip64 /// /// An entry can have this overridden if required Off, + /// /// Zip64 should always be used. /// On, + /// /// #ZipLib will determine use based on entry values when added to archive. /// @@ -38,7 +37,7 @@ public enum CompressionMethod Stored = 0, /// - /// Common Zip compression method using a sliding dictionary + /// Common Zip compression method using a sliding dictionary /// of up to 32KB and secondary compression from Huffman/Shannon-Fano trees /// Deflated = 8, @@ -57,7 +56,6 @@ public enum CompressionMethod /// WinZip special for AES encryption, Now supported by #Zip. /// WinZipAES = 99, - } /// @@ -69,54 +67,67 @@ public enum EncryptionAlgorithm /// No encryption has been used. /// None = 0, + /// /// Encrypted using PKZIP 2.0 or 'classic' encryption. /// PkzipClassic = 1, + /// /// DES encryption has been used. /// Des = 0x6601, + /// /// RC2 encryption has been used for encryption. /// RC2 = 0x6602, + /// /// Triple DES encryption with 168 bit keys has been used for this entry. /// TripleDes168 = 0x6603, + /// /// Triple DES with 112 bit keys has been used for this entry. /// TripleDes112 = 0x6609, + /// /// AES 128 has been used for encryption. /// Aes128 = 0x660e, + /// /// AES 192 has been used for encryption. /// Aes192 = 0x660f, + /// /// AES 256 has been used for encryption. /// Aes256 = 0x6610, + /// /// RC2 corrected has been used for encryption. /// RC2Corrected = 0x6702, + /// /// Blowfish has been used for encryption. /// Blowfish = 0x6720, + /// /// Twofish has been used for encryption. /// Twofish = 0x6721, + /// /// RC4 has been used for encryption. /// RC4 = 0x6801, + /// /// An unknown algorithm has been used for encryption. /// @@ -133,52 +144,64 @@ public enum GeneralBitFlags /// Bit 0 if set indicates that the file is encrypted /// Encrypted = 0x0001, + /// /// Bits 1 and 2 - Two bits defining the compression method (only for Method 6 Imploding and 8,9 Deflating) /// Method = 0x0006, + /// /// Bit 3 if set indicates a trailing data desciptor is appended to the entry data /// Descriptor = 0x0008, + /// /// Bit 4 is reserved for use with method 8 for enhanced deflation /// ReservedPKware4 = 0x0010, + /// /// Bit 5 if set indicates the file contains Pkzip compressed patched data. /// Requires version 2.7 or greater. /// Patched = 0x0020, + /// /// Bit 6 if set indicates strong encryption has been used for this entry. /// StrongEncryption = 0x0040, + /// /// Bit 7 is currently unused /// Unused7 = 0x0080, + /// /// Bit 8 is currently unused /// Unused8 = 0x0100, + /// /// Bit 9 is currently unused /// Unused9 = 0x0200, + /// /// Bit 10 is currently unused /// Unused10 = 0x0400, + /// - /// Bit 11 if set indicates the filename and + /// Bit 11 if set indicates the filename and /// comment fields for this file must be encoded using UTF-8. /// UnicodeText = 0x0800, + /// /// Bit 12 is documented as being reserved by PKware for enhanced compression. /// EnhancedCompress = 0x1000, + /// /// Bit 13 if set indicates that values in the local header are masked to hide /// their actual values, and the central directory is encrypted. @@ -187,17 +210,19 @@ public enum GeneralBitFlags /// Used when encrypting the central directory contents. /// HeaderMasked = 0x2000, + /// /// Bit 14 is documented as being reserved for use by PKware /// ReservedPkware14 = 0x4000, + /// /// Bit 15 is documented as being reserved for use by PKware /// ReservedPkware15 = 0x8000 } - #endregion + #endregion Enumerations /// /// This class contains constants used for Zip format files @@ -205,6 +230,7 @@ public enum GeneralBitFlags public static class ZipConstants { #region Versions + /// /// The version made by field for entries in the central header when created by this library /// @@ -244,9 +270,11 @@ public static class ZipConstants /// The version required for Zip64 extensions (4.5 or higher) /// public const int VersionZip64 = 45; - #endregion + + #endregion Versions #region Header Sizes + /// /// Size of local entry header (excluding variable length fields at end) /// @@ -306,7 +334,8 @@ public static class ZipConstants /// [Obsolete("Use CryptoHeaderSize instead")] public const int CRYPTO_HEADER_SIZE = 12; - #endregion + + #endregion Header Sizes #region Header Signatures @@ -419,7 +448,8 @@ public static class ZipConstants /// [Obsolete("Use EndOfCentralDirectorySignature instead")] public const int ENDSIG = 'P' | ('K' << 8) | (5 << 16) | (6 << 24); - #endregion + + #endregion Header Signatures /// /// Default encoding used for string conversion. 0 gives the default system OEM code page. @@ -463,7 +493,5 @@ public static byte[] ConvertToArray(string str) [Obsolete("Use ZipStrings.ConvertToArray instead")] public static byte[] ConvertToArray(int flags, string str) => ZipStrings.ConvertToArray(flags, str); - - } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs index 5a39fa385..572108f0f 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs @@ -12,82 +12,102 @@ public enum HostSystemID /// Host system = MSDOS /// Msdos = 0, + /// /// Host system = Amiga /// Amiga = 1, + /// /// Host system = Open VMS /// OpenVms = 2, + /// /// Host system = Unix /// Unix = 3, + /// /// Host system = VMCms /// VMCms = 4, + /// /// Host system = Atari ST /// AtariST = 5, + /// /// Host system = OS2 /// OS2 = 6, + /// /// Host system = Macintosh /// Macintosh = 7, + /// /// Host system = ZSystem /// ZSystem = 8, + /// /// Host system = Cpm /// Cpm = 9, + /// /// Host system = Windows NT /// WindowsNT = 10, + /// /// Host system = MVS /// MVS = 11, + /// /// Host system = VSE /// Vse = 12, + /// /// Host system = Acorn RISC /// AcornRisc = 13, + /// /// Host system = VFAT /// Vfat = 14, + /// /// Host system = Alternate MVS /// AlternateMvs = 15, + /// /// Host system = BEOS /// BeOS = 16, + /// /// Host system = Tandem /// Tandem = 17, + /// /// Host system = OS400 /// OS400 = 18, + /// /// Host system = OSX /// OSX = 19, + /// /// Host system = WinZIP AES /// @@ -97,7 +117,7 @@ public enum HostSystemID /// /// This class represents an entry in a zip archive. This can be a file /// or a directory - /// ZipFile and ZipInputStream will give you instances of this class as + /// ZipFile and ZipInputStream will give you instances of this class as /// information about the members in an archive. ZipOutputStream /// uses an instance of this class when creating an entry in a Zip file. ///
@@ -106,7 +126,7 @@ public enum HostSystemID public class ZipEntry { [Flags] - enum Known : byte + private enum Known : byte { None = 0, Size = 0x01, @@ -117,6 +137,7 @@ enum Known : byte } #region Constructors + /// /// Creates a zip entry with the given name. /// @@ -138,7 +159,7 @@ public ZipEntry(string name) ///
/// /// The name for this entry. Can include directory components. - /// The convention for names is 'unix' style paths with no device names and + /// The convention for names is 'unix' style paths with no device names and /// path elements separated by '/' characters. This is not enforced see CleanName /// on how to ensure names are valid if this is desired. /// @@ -174,15 +195,18 @@ internal ZipEntry(string name, int versionRequiredToExtract) internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo, CompressionMethod method) { - if (name == null) { + if (name == null) + { throw new ArgumentNullException(nameof(name)); } - if (name.Length > 0xffff) { + if (name.Length > 0xffff) + { throw new ArgumentException("Name is too long", nameof(name)); } - if ((versionRequiredToExtract != 0) && (versionRequiredToExtract < 10)) { + if ((versionRequiredToExtract != 0) && (versionRequiredToExtract < 10)) + { throw new ArgumentOutOfRangeException(nameof(versionRequiredToExtract)); } @@ -204,7 +228,8 @@ internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo, [Obsolete("Use Clone instead")] public ZipEntry(ZipEntry entry) { - if (entry == null) { + if (entry == null) + { throw new ArgumentNullException(nameof(entry)); } @@ -226,19 +251,22 @@ public ZipEntry(ZipEntry entry) forceZip64_ = entry.forceZip64_; - if (entry.extra != null) { + if (entry.extra != null) + { extra = new byte[entry.extra.Length]; Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length); } } - #endregion + #endregion Constructors /// /// Get a value indicating wether the entry has a CRC value available. /// - public bool HasCrc { - get { + public bool HasCrc + { + get + { return (known & Known.Crc) != 0; } } @@ -248,14 +276,20 @@ public bool HasCrc { /// A simple helper routine to aid interpretation of flags /// /// This is an assistant that interprets the flags property. - public bool IsCrypted { - get { + public bool IsCrypted + { + get + { return (flags & 1) != 0; } - set { - if (value) { + set + { + if (value) + { flags |= 1; - } else { + } + else + { flags &= ~1; } } @@ -266,14 +300,20 @@ public bool IsCrypted { /// encoded in unicode UTF8. /// /// This is an assistant that interprets the flags property. - public bool IsUnicodeText { - get { + public bool IsUnicodeText + { + get + { return (flags & (int)GeneralBitFlags.UnicodeText) != 0; } - set { - if (value) { + set + { + if (value) + { flags |= (int)GeneralBitFlags.UnicodeText; - } else { + } + else + { flags &= ~(int)GeneralBitFlags.UnicodeText; } } @@ -282,12 +322,15 @@ public bool IsUnicodeText { /// /// Value used during password checking for PKZIP 2.0 / 'classic' encryption. /// - internal byte CryptoCheckValue { - get { + internal byte CryptoCheckValue + { + get + { return cryptoCheckValue_; } - set { + set + { cryptoCheckValue_ = value; } } @@ -323,11 +366,14 @@ internal byte CryptoCheckValue { /// /// /// - public int Flags { - get { + public int Flags + { + get + { return flags; } - set { + set + { flags = value; } } @@ -336,11 +382,14 @@ public int Flags { /// Get/Set index of this entry in Zip file /// /// This is only valid when the entry is part of a - public long ZipFileIndex { - get { + public long ZipFileIndex + { + get + { return zipFileIndex; } - set { + set + { zipFileIndex = value; } } @@ -348,11 +397,14 @@ public long ZipFileIndex { /// /// Get/set offset for use in central header /// - public long Offset { - get { + public long Offset + { + get + { return offset; } - set { + set + { offset = value; } } @@ -362,16 +414,22 @@ public long Offset { /// The values of this are operating system dependant see /// HostSystem for details /// - public int ExternalFileAttributes { - get { - if ((known & Known.ExternalAttributes) == 0) { + public int ExternalFileAttributes + { + get + { + if ((known & Known.ExternalAttributes) == 0) + { return -1; - } else { + } + else + { return externalFileAttributes; } } - set { + set + { externalFileAttributes = value; known |= Known.ExternalAttributes; } @@ -379,11 +437,13 @@ public int ExternalFileAttributes { /// /// Get the version made by for this entry or zero if unknown. - /// The value / 10 indicates the major version number, and + /// The value / 10 indicates the major version number, and /// the value mod 10 is the minor version number /// - public int VersionMadeBy { - get { + public int VersionMadeBy + { + get + { return (versionMadeBy & 0xff); } } @@ -391,8 +451,10 @@ public int VersionMadeBy { /// /// Get a value indicating this entry is for a DOS/Windows system. /// - public bool IsDOSEntry { - get { + public bool IsDOSEntry + { + get + { return ((HostSystem == (int)HostSystemID.Msdos) || (HostSystem == (int)HostSystemID.WindowsNT)); } @@ -404,12 +466,13 @@ public bool IsDOSEntry { /// and match the values /// /// The attributes to test. - /// Returns true if the external attributes are known to be DOS/Windows + /// Returns true if the external attributes are known to be DOS/Windows /// based and have the same attributes set as the value passed. - bool HasDosAttributes(int attributes) + private bool HasDosAttributes(int attributes) { bool result = false; - if ((known & Known.ExternalAttributes) != 0) { + if ((known & Known.ExternalAttributes) != 0) + { result |= (((HostSystem == (int)HostSystemID.Msdos) || (HostSystem == (int)HostSystemID.WindowsNT)) && (ExternalFileAttributes & attributes) == attributes); @@ -423,7 +486,7 @@ bool HasDosAttributes(int attributes) /// by PKZIP for DOS version 2.04g then this value will be zero. Otherwise the value /// will be non-zero and identify the host system on which the attributes are compatible. /// - /// + /// /// /// The values for this as defined in the Zip File format and by others are shown below. The values are somewhat /// misleading in some cases as they are not all used as shown. You should consult the relevant documentation @@ -454,12 +517,15 @@ bool HasDosAttributes(int attributes) /// remainder - unused /// /// - public int HostSystem { - get { + public int HostSystem + { + get + { return (versionMadeBy >> 8) & 0xff; } - set { + set + { versionMadeBy &= 0xff; versionMadeBy |= (ushort)((value & 0xff) << 8); } @@ -467,7 +533,7 @@ public int HostSystem { /// /// Get minimum Zip feature version required to extract this entry - /// + /// /// /// Minimum features are defined as:
/// 1.0 - Default value
@@ -495,24 +561,40 @@ public int HostSystem { /// 6.3 - File is encrypted using Twofish
///
/// - public int Version { - get { + public int Version + { + get + { // Return recorded version if known. - if (versionToExtract != 0) { + if (versionToExtract != 0) + { return versionToExtract & 0x00ff; // Only lower order byte. High order is O/S file system. - } else { + } + else + { int result = 10; - if (AESKeySize > 0) { + if (AESKeySize > 0) + { result = ZipConstants.VERSION_AES; // Ver 5.1 = AES - } else if (CentralHeaderRequiresZip64) { + } + else if (CentralHeaderRequiresZip64) + { result = ZipConstants.VersionZip64; - } else if (CompressionMethod.Deflated == method) { + } + else if (CompressionMethod.Deflated == method) + { result = 20; - } else if (IsDirectory == true) { + } + else if (IsDirectory == true) + { result = 20; - } else if (IsCrypted == true) { + } + else if (IsCrypted == true) + { result = 20; - } else if (HasDosAttributes(0x08)) { + } + else if (HasDosAttributes(0x08)) + { result = 11; } return result; @@ -523,10 +605,12 @@ public int Version { /// /// Get a value indicating whether this entry can be decompressed by the library. /// - /// This is based on the and + /// This is based on the and /// wether the compression method is supported. - public bool CanDecompress { - get { + public bool CanDecompress + { + get + { return (Version <= ZipConstants.VersionMadeBy) && ((Version == 10) || (Version == 11) || @@ -555,18 +639,22 @@ public bool IsZip64Forced() } /// - /// Gets a value indicating if the entry requires Zip64 extensions + /// Gets a value indicating if the entry requires Zip64 extensions /// to store the full entry values. /// /// A value of true if a local header requires Zip64 extensions; false if not. - public bool LocalHeaderRequiresZip64 { - get { + public bool LocalHeaderRequiresZip64 + { + get + { bool result = forceZip64_; - if (!result) { + if (!result) + { ulong trueCompressedSize = compressedSize; - if ((versionToExtract == 0) && IsCrypted) { + if ((versionToExtract == 0) && IsCrypted) + { trueCompressedSize += ZipConstants.CryptoHeaderSize; } @@ -584,8 +672,10 @@ public bool LocalHeaderRequiresZip64 { /// /// Get a value indicating wether the central directory entry requires Zip64 extensions to be stored. /// - public bool CentralHeaderRequiresZip64 { - get { + public bool CentralHeaderRequiresZip64 + { + get + { return LocalHeaderRequiresZip64 || (offset >= uint.MaxValue); } } @@ -596,17 +686,24 @@ public bool CentralHeaderRequiresZip64 { /// /// The MS-DOS date format can only represent dates between 1/1/1980 and 12/31/2107. /// - public long DosTime { - get { - if ((known & Known.Time) == 0) { + public long DosTime + { + get + { + if ((known & Known.Time) == 0) + { return 0; - } else { + } + else + { return dosTime; } } - set { - unchecked { + set + { + unchecked + { dosTime = (uint)value; } @@ -633,7 +730,8 @@ public DateTime DateTime return new System.DateTime((int)year, (int)mon, day, (int)hrs, (int)min, (int)sec); } - set { + set + { var year = (uint)value.Year; var month = (uint)value.Month; var day = (uint)value.Day; @@ -641,14 +739,17 @@ public DateTime DateTime var minute = (uint)value.Minute; var second = (uint)value.Second; - if (year < 1980) { + if (year < 1980) + { year = 1980; month = 1; day = 1; hour = 0; minute = 0; second = 0; - } else if (year > 2107) { + } + else if (year > 2107) + { year = 2107; month = 12; day = 31; @@ -675,8 +776,10 @@ public DateTime DateTime /// Dos device names like C: should also be removed. /// See the class, or /// - public string Name { - get { + public string Name + { + get + { return name; } } @@ -689,11 +792,14 @@ public string Name { ///
/// Setting the size before adding an entry to an archive can help /// avoid compatability problems with some archivers which dont understand Zip64 extensions. - public long Size { - get { + public long Size + { + get + { return (known & Known.Size) != 0 ? (long)size : -1L; } - set { + set + { this.size = (ulong)value; this.known |= Known.Size; } @@ -705,11 +811,14 @@ public long Size { /// /// The compressed entry size or -1 if unknown. /// - public long CompressedSize { - get { + public long CompressedSize + { + get + { return (known & Known.CompressedSize) != 0 ? (long)compressedSize : -1L; } - set { + set + { this.compressedSize = (ulong)value; this.known |= Known.CompressedSize; } @@ -724,12 +833,16 @@ public long CompressedSize { /// /// The crc value or -1 if unknown. /// - public long Crc { - get { + public long Crc + { + get + { return (known & Known.Crc) != 0 ? crc & 0xffffffffL : -1L; } - set { - if (((ulong)crc & 0xffffffff00000000L) != 0) { + set + { + if (((ulong)crc & 0xffffffff00000000L) != 0) + { throw new ArgumentOutOfRangeException(nameof(value)); } this.crc = (uint)value; @@ -745,13 +858,17 @@ public long Crc { /// /// /// - public CompressionMethod CompressionMethod { - get { + public CompressionMethod CompressionMethod + { + get + { return method; } - set { - if (!IsCompressionMethodSupported(value)) { + set + { + if (!IsCompressionMethodSupported(value)) + { throw new NotSupportedException("Compression method not supported"); } this.method = value; @@ -763,8 +880,10 @@ public CompressionMethod CompressionMethod { /// Returns same value as CompressionMethod except when AES encrypting, which /// places 99 in the method and places the real method in the extra data. /// - internal CompressionMethod CompressionMethodForHeader { - get { + internal CompressionMethod CompressionMethodForHeader + { + get + { return (AESKeySize > 0) ? CompressionMethod.WinZipAES : method; } } @@ -778,19 +897,25 @@ internal CompressionMethod CompressionMethodForHeader { /// /// Extra data or null if not set. /// - public byte[] ExtraData { - - get { + public byte[] ExtraData + { + get + { // TODO: This is slightly safer but less efficient. Think about wether it should change. // return (byte[]) extra.Clone(); return extra; } - set { - if (value == null) { + set + { + if (value == null) + { extra = null; - } else { - if (value.Length > 0xffff) { + } + else + { + if (value.Length > 0xffff) + { throw new System.ArgumentOutOfRangeException(nameof(value)); } @@ -800,38 +925,47 @@ public byte[] ExtraData { } } - /// /// For AES encrypted files returns or sets the number of bits of encryption (128, 192 or 256). /// When setting, only 0 (off), 128 or 256 is supported. /// - public int AESKeySize { - get { + public int AESKeySize + { + get + { // the strength (1 or 3) is in the entry header - switch (_aesEncryptionStrength) { + switch (_aesEncryptionStrength) + { case 0: return 0; // Not AES case 1: return 128; + case 2: return 192; // Not used by WinZip case 3: return 256; + default: throw new ZipException("Invalid AESEncryptionStrength " + _aesEncryptionStrength); } } - set { - switch (value) { + set + { + switch (value) + { case 0: _aesEncryptionStrength = 0; break; + case 128: _aesEncryptionStrength = 1; break; + case 256: _aesEncryptionStrength = 3; break; + default: throw new ZipException("AESKeySize must be 0, 128 or 256: " + value); } @@ -842,17 +976,21 @@ public int AESKeySize { /// AES Encryption strength for storage in extra data in entry header. /// 1 is 128 bit, 2 is 192 bit, 3 is 256 bit. /// - internal byte AESEncryptionStrength { - get { + internal byte AESEncryptionStrength + { + get + { return (byte)_aesEncryptionStrength; } } /// - /// Returns the length of the salt, in bytes + /// Returns the length of the salt, in bytes /// - internal int AESSaltLen { - get { + internal int AESSaltLen + { + get + { // Key size -> Salt length: 128 bits = 8 bytes, 192 bits = 12 bytes, 256 bits = 16 bytes. return AESKeySize / 16; } @@ -861,8 +999,10 @@ internal int AESSaltLen { /// /// Number of extra bytes required to hold the AES Header fields (Salt, Pwd verify, AuthCode) /// - internal int AESOverheadSize { - get { + internal int AESOverheadSize + { + get + { // File format: // Bytes Content // Variable Salt value @@ -883,72 +1023,82 @@ internal void ProcessExtraData(bool localHeader) { var extraData = new ZipExtraData(this.extra); - if (extraData.Find(0x0001)) { + if (extraData.Find(0x0001)) + { // Version required to extract is ignored here as some archivers dont set it correctly // in theory it should be version 45 or higher // The recorded size will change but remember that this is zip64. forceZip64_ = true; - if (extraData.ValueLength < 4) { + if (extraData.ValueLength < 4) + { throw new ZipException("Extra data extended Zip64 information length is invalid"); } - // (localHeader ||) was deleted, because actually there is no specific difference with reading sizes between local header & central directory - // https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT + // (localHeader ||) was deleted, because actually there is no specific difference with reading sizes between local header & central directory + // https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT // ... // 4.4 Explanation of fields // ... // 4.4.8 compressed size: (4 bytes) // 4.4.9 uncompressed size: (4 bytes) - // + // // The size of the file compressed (4.4.8) and uncompressed, - // (4.4.9) respectively. When a decryption header is present it + // (4.4.9) respectively. When a decryption header is present it // will be placed in front of the file data and the value of the // compressed file size will include the bytes of the decryption - // header. If bit 3 of the general purpose bit flag is set, - // these fields are set to zero in the local header and the + // header. If bit 3 of the general purpose bit flag is set, + // these fields are set to zero in the local header and the // correct values are put in the data descriptor and // in the central directory. If an archive is in ZIP64 format // and the value in this field is 0xFFFFFFFF, the size will be - // in the corresponding 8 byte ZIP64 extended information + // in the corresponding 8 byte ZIP64 extended information // extra field. When encrypting the central directory, if the - // local header is not in ZIP64 format and general purpose bit - // flag 13 is set indicating masking, the value stored for the - // uncompressed size in the Local Header will be zero. - // + // local header is not in ZIP64 format and general purpose bit + // flag 13 is set indicating masking, the value stored for the + // uncompressed size in the Local Header will be zero. + // // Othewise there is problem with minizip implementation - if (size == uint.MaxValue) { + if (size == uint.MaxValue) + { size = (ulong)extraData.ReadLong(); } - if (compressedSize == uint.MaxValue) { + if (compressedSize == uint.MaxValue) + { compressedSize = (ulong)extraData.ReadLong(); } - if (!localHeader && (offset == uint.MaxValue)) { + if (!localHeader && (offset == uint.MaxValue)) + { offset = extraData.ReadLong(); } // Disk number on which file starts is ignored - } else { + } + else + { if ( ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) && ((size == uint.MaxValue) || (compressedSize == uint.MaxValue)) - ) { + ) + { throw new ZipException("Zip64 Extended information required but is missing."); } } DateTime = GetDateTime(extraData); - if (method == CompressionMethod.WinZipAES) { + if (method == CompressionMethod.WinZipAES) + { ProcessAESExtraData(extraData); } } - private DateTime GetDateTime(ZipExtraData extraData) { + private DateTime GetDateTime(ZipExtraData extraData) + { // Check for NT timestamp - // NOTE: Disable by default to match behavior of InfoZIP + // NOTE: Disable by default to match behavior of InfoZIP #if RESPECT_NT_TIMESTAMP NTTaggedData ntData = extraData.GetData(); if (ntData != null) @@ -979,8 +1129,8 @@ private DateTime GetDateTime(ZipExtraData extraData) { // private void ProcessAESExtraData(ZipExtraData extraData) { - - if (extraData.Find(0x9901)) { + if (extraData.Find(0x9901)) + { // Set version and flag for Zipfile.CreateAndInitDecryptionStream versionToExtract = ZipConstants.VERSION_AES; // Ver 5.1 = AES see "Version" getter // Set StrongEncryption flag for ZipFile.CreateAndInitDecryptionStream @@ -997,7 +1147,8 @@ private void ProcessAESExtraData(ZipExtraData extraData) _aesVer = ver; _aesEncryptionStrength = encrStrength; method = (CompressionMethod)actualCompress; - } else + } + else throw new ZipException("AES Extra Data missing"); } @@ -1014,19 +1165,23 @@ private void ProcessAESExtraData(ZipExtraData extraData) /// A comment is only available for entries when read via the class. /// The class doesnt have the comment data available. /// - public string Comment { - get { + public string Comment + { + get + { return comment; } - set { + set + { // This test is strictly incorrect as the length is in characters // while the storage limit is in bytes. - // While the test is partially correct in that a comment of this length or greater + // While the test is partially correct in that a comment of this length or greater // is definitely invalid, shorter comments may also have an invalid length // where there are multi-byte characters // The full test is not possible here however as the code page to apply conversions with // isnt available. - if ((value != null) && (value.Length > 0xffff)) { + if ((value != null) && (value.Length > 0xffff)) + { throw new ArgumentOutOfRangeException(nameof(value), "cannot exceed 65535"); } @@ -1044,8 +1199,10 @@ public string Comment { /// Currently only dos/windows attributes are tested in this manner. /// The trailing slash convention should always be followed. /// - public bool IsDirectory { - get { + public bool IsDirectory + { + get + { int nameLength = name.Length; bool result = ((nameLength > 0) && @@ -1063,8 +1220,10 @@ public bool IsDirectory { /// This only takes account of DOS/Windows attributes. Other operating systems are ignored. /// For linux and others the result may be incorrect. /// - public bool IsFile { - get { + public bool IsFile + { + get + { return !IsDirectory && !HasDosAttributes(8); } } @@ -1079,6 +1238,7 @@ public bool IsCompressionMethodSupported() } #region ICloneable Members + /// /// Creates a copy of this zip entry. /// @@ -1088,7 +1248,8 @@ public object Clone() var result = (ZipEntry)this.MemberwiseClone(); // Ensure extra data is unique if it exists. - if (extra != null) { + if (extra != null) + { result.extra = new byte[extra.Length]; Array.Copy(extra, 0, result.extra, 0, extra.Length); } @@ -1096,7 +1257,7 @@ public object Clone() return result; } - #endregion + #endregion ICloneable Members /// /// Gets a string representation of this ZipEntry. @@ -1134,11 +1295,13 @@ public static bool IsCompressionMethodSupported(CompressionMethod method) /// public static string CleanName(string name) { - if (name == null) { + if (name == null) + { return string.Empty; } - if (Path.IsPathRooted(name)) { + if (Path.IsPathRooted(name)) + { // NOTE: // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt name = name.Substring(Path.GetPathRoot(name).Length); @@ -1146,39 +1309,42 @@ public static string CleanName(string name) name = name.Replace(@"\", "/"); - while ((name.Length > 0) && (name[0] == '/')) { + while ((name.Length > 0) && (name[0] == '/')) + { name = name.Remove(0, 1); } return name; } #region Instance Fields - Known known; - int externalFileAttributes = -1; // contains external attributes (O/S dependant) - ushort versionMadeBy; // Contains host system and version information - // only relevant for central header entries + private Known known; + private int externalFileAttributes = -1; // contains external attributes (O/S dependant) + + private ushort versionMadeBy; // Contains host system and version information + // only relevant for central header entries + + private string name; + private ulong size; + private ulong compressedSize; + private ushort versionToExtract; // Version required to extract (library handles <= 2.0) + private uint crc; + private uint dosTime; - string name; - ulong size; - ulong compressedSize; - ushort versionToExtract; // Version required to extract (library handles <= 2.0) - uint crc; - uint dosTime; + private CompressionMethod method = CompressionMethod.Deflated; + private byte[] extra; + private string comment; - CompressionMethod method = CompressionMethod.Deflated; - byte[] extra; - string comment; + private int flags; // general purpose bit flags - int flags; // general purpose bit flags + private long zipFileIndex = -1; // used by ZipFile + private long offset; // used by ZipFile and ZipOutputStream - long zipFileIndex = -1; // used by ZipFile - long offset; // used by ZipFile and ZipOutputStream + private bool forceZip64_; + private byte cryptoCheckValue_; + private int _aesVer; // Version number (2 = AE-2 ?). Assigned but not used. + private int _aesEncryptionStrength; // Encryption strength 1 = 128 2 = 192 3 = 256 - bool forceZip64_; - byte cryptoCheckValue_; - int _aesVer; // Version number (2 = AE-2 ?). Assigned but not used. - int _aesEncryptionStrength; // Encryption strength 1 = 128 2 = 192 3 = 256 - #endregion + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs index d34c626c9..d5750f0a6 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs @@ -1,6 +1,6 @@ +using ICSharpCode.SharpZipLib.Core; using System; using System.IO; -using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.Zip { @@ -10,6 +10,7 @@ namespace ICSharpCode.SharpZipLib.Zip public class ZipEntryFactory : IEntryFactory { #region Enumerations + /// /// Defines the possible values to be used for the . /// @@ -19,39 +20,47 @@ public enum TimeSetting /// Use the recorded LastWriteTime value for the file. /// LastWriteTime, + /// /// Use the recorded LastWriteTimeUtc value for the file /// LastWriteTimeUtc, + /// /// Use the recorded CreateTime value for the file. /// CreateTime, + /// /// Use the recorded CreateTimeUtc value for the file. /// CreateTimeUtc, + /// /// Use the recorded LastAccessTime value for the file. /// LastAccessTime, + /// /// Use the recorded LastAccessTimeUtc value for the file. /// LastAccessTimeUtc, + /// /// Use a fixed value. /// /// The actual value used can be - /// specified via the constructor or + /// specified via the constructor or /// using the with the setting set /// to which will use the when this class was constructed. /// The property can also be used to set this value. Fixed, } - #endregion + + #endregion Enumerations #region Constructors + /// /// Initialise a new instance of the class. /// @@ -66,7 +75,7 @@ public ZipEntryFactory() /// Initialise a new instance of using the specified /// /// The time setting to use when creating Zip entries. - public ZipEntryFactory(TimeSetting timeSetting): this() + public ZipEntryFactory(TimeSetting timeSetting) : this() { timeSetting_ = timeSetting; } @@ -75,27 +84,33 @@ public ZipEntryFactory(TimeSetting timeSetting): this() /// Initialise a new instance of using the specified /// /// The time to set all values to. - public ZipEntryFactory(DateTime time): this() + public ZipEntryFactory(DateTime time) : this() { timeSetting_ = TimeSetting.Fixed; FixedDateTime = time; } - #endregion + #endregion Constructors #region Properties + /// /// Get / set the to be used when creating new values. /// /// /// Setting this property to null will cause a default name transform to be used. /// - public INameTransform NameTransform { + public INameTransform NameTransform + { get { return nameTransform_; } - set { - if (value == null) { + set + { + if (value == null) + { nameTransform_ = new ZipNameTransform(); - } else { + } + else + { nameTransform_ = value; } } @@ -104,7 +119,8 @@ public INameTransform NameTransform { /// /// Get / set the in use. /// - public TimeSetting Setting { + public TimeSetting Setting + { get { return timeSetting_; } set { timeSetting_ = value; } } @@ -112,10 +128,13 @@ public TimeSetting Setting { /// /// Get / set the value to use when is set to /// - public DateTime FixedDateTime { + public DateTime FixedDateTime + { get { return fixedDateTime_; } - set { - if (value.Year < 1970) { + set + { + if (value.Year < 1970) + { throw new ArgumentException("Value is too old to be valid", nameof(value)); } fixedDateTime_ = value; @@ -126,7 +145,8 @@ public DateTime FixedDateTime { /// A bitmask defining the attributes to be retrieved from the actual file. /// /// The default is to get all possible attributes from the actual file. - public int GetAttributes { + public int GetAttributes + { get { return getAttributes_; } set { getAttributes_ = value; } } @@ -135,7 +155,8 @@ public int GetAttributes { /// A bitmask defining which attributes are to be set on. /// /// By default no attributes are set on. - public int SetAttributes { + public int SetAttributes + { get { return setAttributes_; } set { setAttributes_ = value; } } @@ -143,12 +164,13 @@ public int SetAttributes { /// /// Get set a value indicating wether unidoce text should be set on. /// - public bool IsUnicodeText { + public bool IsUnicodeText + { get { return isUnicodeText_; } set { isUnicodeText_ = value; } } - #endregion + #endregion Properties #region IEntryFactory Members @@ -189,12 +211,15 @@ public ZipEntry MakeFileEntry(string fileName, string entryName, bool useFileSys bool useAttributes = (setAttributes_ != 0); FileInfo fi = null; - if (useFileSystem) { + if (useFileSystem) + { fi = new FileInfo(fileName); } - if ((fi != null) && fi.Exists) { - switch (timeSetting_) { + if ((fi != null) && fi.Exists) + { + switch (timeSetting_) + { case TimeSetting.CreateTime: result.DateTime = fi.CreationTime; break; @@ -231,13 +256,17 @@ public ZipEntry MakeFileEntry(string fileName, string entryName, bool useFileSys useAttributes = true; externalAttributes = ((int)fi.Attributes & getAttributes_); - } else { - if (timeSetting_ == TimeSetting.Fixed) { + } + else + { + if (timeSetting_ == TimeSetting.Fixed) + { result.DateTime = fixedDateTime_; } } - if (useAttributes) { + if (useAttributes) + { externalAttributes |= setAttributes_; result.ExternalFileAttributes = externalAttributes; } @@ -263,7 +292,6 @@ public ZipEntry MakeDirectoryEntry(string directoryName) /// Returns a new representing a directory. public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) { - var result = new ZipEntry(nameTransform_.TransformDirectory(directoryName)); result.IsUnicodeText = isUnicodeText_; result.Size = 0; @@ -272,13 +300,15 @@ public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) DirectoryInfo di = null; - if (useFileSystem) { + if (useFileSystem) + { di = new DirectoryInfo(directoryName); } - - if ((di != null) && di.Exists) { - switch (timeSetting_) { + if ((di != null) && di.Exists) + { + switch (timeSetting_) + { case TimeSetting.CreateTime: result.DateTime = di.CreationTime; break; @@ -312,8 +342,11 @@ public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) } externalAttributes = ((int)di.Attributes & getAttributes_); - } else { - if (timeSetting_ == TimeSetting.Fixed) { + } + else + { + if (timeSetting_ == TimeSetting.Fixed) + { result.DateTime = fixedDateTime_; } } @@ -325,16 +358,18 @@ public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) return result; } - #endregion + #endregion IEntryFactory Members #region Instance Fields - INameTransform nameTransform_; - DateTime fixedDateTime_ = DateTime.Now; - TimeSetting timeSetting_; - bool isUnicodeText_; - - int getAttributes_ = -1; - int setAttributes_; - #endregion + + private INameTransform nameTransform_; + private DateTime fixedDateTime_ = DateTime.Now; + private TimeSetting timeSetting_; + private bool isUnicodeText_; + + private int getAttributes_ = -1; + private int setAttributes_; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs index cd18e7016..28843883e 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs @@ -7,7 +7,6 @@ namespace ICSharpCode.SharpZipLib.Zip /// public class ZipException : SharpZipBaseException { - /// /// Initialise a new instance of . /// diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs index 4582d9afd..9e0e8037f 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs @@ -50,7 +50,8 @@ public RawTaggedData(short tag) /// /// Get the ID for this tagged data value. /// - public short TagID { + public short TagID + { get { return _tag; } set { _tag = value; } } @@ -63,7 +64,8 @@ public short TagID { /// The number of bytes available. public void SetData(byte[] data, int offset, int count) { - if (data == null) { + if (data == null) + { throw new ArgumentNullException(nameof(data)); } @@ -80,25 +82,28 @@ public byte[] GetData() return _data; } - #endregion + #endregion ITaggedData Members /// /// Get /set the binary data representing this instance. /// /// The raw binary data representing this instance. - public byte[] Data { + public byte[] Data + { get { return _data; } set { _data = value; } } #region Instance Fields + /// /// The tag ID for this instance. /// - short _tag; + private short _tag; + + private byte[] _data; - byte[] _data; - #endregion + #endregion Instance Fields } /// @@ -133,7 +138,8 @@ public enum Flags : byte /// /// Get the ID /// - public short TagID { + public short TagID + { get { return 0x5455; } } @@ -146,7 +152,8 @@ public short TagID { public void SetData(byte[] data, int index, int count) { using (MemoryStream ms = new MemoryStream(data, index, count, false)) - using (ZipHelperStream helperStream = new ZipHelperStream(ms)) { + using (ZipHelperStream helperStream = new ZipHelperStream(ms)) + { // bit 0 if set, modification time is present // bit 1 if set, access time is present // bit 2 if set, creation time is present @@ -163,14 +170,16 @@ public void SetData(byte[] data, int index, int count) if (count <= 5) return; } - if ((_flags & Flags.AccessTime) != 0) { + if ((_flags & Flags.AccessTime) != 0) + { int iTime = helperStream.ReadLEInt(); _lastAccessTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) + new TimeSpan(0, 0, 0, iTime, 0); } - if ((_flags & Flags.CreateTime) != 0) { + if ((_flags & Flags.CreateTime) != 0) + { int iTime = helperStream.ReadLEInt(); _createTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) + @@ -186,20 +195,24 @@ public void SetData(byte[] data, int index, int count) public byte[] GetData() { using (MemoryStream ms = new MemoryStream()) - using (ZipHelperStream helperStream = new ZipHelperStream(ms)) { + using (ZipHelperStream helperStream = new ZipHelperStream(ms)) + { helperStream.IsStreamOwner = false; helperStream.WriteByte((byte)_flags); // Flags - if ((_flags & Flags.ModificationTime) != 0) { + if ((_flags & Flags.ModificationTime) != 0) + { TimeSpan span = _modificationTime - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var seconds = (int)span.TotalSeconds; helperStream.WriteLEInt(seconds); } - if ((_flags & Flags.AccessTime) != 0) { + if ((_flags & Flags.AccessTime) != 0) + { TimeSpan span = _lastAccessTime - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var seconds = (int)span.TotalSeconds; helperStream.WriteLEInt(seconds); } - if ((_flags & Flags.CreateTime) != 0) { + if ((_flags & Flags.CreateTime) != 0) + { TimeSpan span = _createTime - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var seconds = (int)span.TotalSeconds; helperStream.WriteLEInt(seconds); @@ -208,7 +221,7 @@ public byte[] GetData() } } - #endregion + #endregion ITaggedData Members /// /// Test a value to see if is valid and can be represented here. @@ -232,10 +245,13 @@ public static bool IsValidValue(DateTime value) /// /// /// - public DateTime ModificationTime { + public DateTime ModificationTime + { get { return _modificationTime; } - set { - if (!IsValidValue(value)) { + set + { + if (!IsValidValue(value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } @@ -249,10 +265,13 @@ public DateTime ModificationTime { /// /// /// - public DateTime AccessTime { + public DateTime AccessTime + { get { return _lastAccessTime; } - set { - if (!IsValidValue(value)) { + set + { + if (!IsValidValue(value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } @@ -266,10 +285,13 @@ public DateTime AccessTime { /// /// /// - public DateTime CreateTime { + public DateTime CreateTime + { get { return _createTime; } - set { - if (!IsValidValue(value)) { + set + { + if (!IsValidValue(value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } @@ -288,11 +310,13 @@ public Flags Include } #region Instance Fields - Flags _flags; - DateTime _modificationTime = new DateTime(1970, 1, 1); - DateTime _lastAccessTime = new DateTime(1970, 1, 1); - DateTime _createTime = new DateTime(1970, 1, 1); - #endregion + + private Flags _flags; + private DateTime _modificationTime = new DateTime(1970, 1, 1); + private DateTime _lastAccessTime = new DateTime(1970, 1, 1); + private DateTime _createTime = new DateTime(1970, 1, 1); + + #endregion Instance Fields } /// @@ -303,7 +327,8 @@ public class NTTaggedData : ITaggedData /// /// Get the ID for this tagged data value. /// - public short TagID { + public short TagID + { get { return 10; } } @@ -316,13 +341,17 @@ public short TagID { public void SetData(byte[] data, int index, int count) { using (MemoryStream ms = new MemoryStream(data, index, count, false)) - using (ZipHelperStream helperStream = new ZipHelperStream(ms)) { + using (ZipHelperStream helperStream = new ZipHelperStream(ms)) + { helperStream.ReadLEInt(); // Reserved - while (helperStream.Position < helperStream.Length) { + while (helperStream.Position < helperStream.Length) + { int ntfsTag = helperStream.ReadLEShort(); int ntfsLength = helperStream.ReadLEShort(); - if (ntfsTag == 1) { - if (ntfsLength >= 24) { + if (ntfsTag == 1) + { + if (ntfsLength >= 24) + { long lastModificationTicks = helperStream.ReadLELong(); _lastModificationTime = DateTime.FromFileTimeUtc(lastModificationTicks); @@ -333,7 +362,9 @@ public void SetData(byte[] data, int index, int count) _createTime = DateTime.FromFileTimeUtc(createTimeTicks); } break; - } else { + } + else + { // An unknown NTFS tag so simply skip it. helperStream.Seek(ntfsLength, SeekOrigin.Current); } @@ -348,7 +379,8 @@ public void SetData(byte[] data, int index, int count) public byte[] GetData() { using (MemoryStream ms = new MemoryStream()) - using (ZipHelperStream helperStream = new ZipHelperStream(ms)) { + using (ZipHelperStream helperStream = new ZipHelperStream(ms)) + { helperStream.IsStreamOwner = false; helperStream.WriteLEInt(0); // Reserved helperStream.WriteLEShort(1); // Tag @@ -374,9 +406,12 @@ public byte[] GetData() public static bool IsValidValue(DateTime value) { bool result = true; - try { + try + { value.ToFileTimeUtc(); - } catch { + } + catch + { result = false; } return result; @@ -385,10 +420,13 @@ public static bool IsValidValue(DateTime value) /// /// Get/set the last modification time. /// - public DateTime LastModificationTime { + public DateTime LastModificationTime + { get { return _lastModificationTime; } - set { - if (!IsValidValue(value)) { + set + { + if (!IsValidValue(value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } _lastModificationTime = value; @@ -398,10 +436,13 @@ public DateTime LastModificationTime { /// /// Get /set the create time /// - public DateTime CreateTime { + public DateTime CreateTime + { get { return _createTime; } - set { - if (!IsValidValue(value)) { + set + { + if (!IsValidValue(value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } _createTime = value; @@ -411,10 +452,13 @@ public DateTime CreateTime { /// /// Get /set the last access time. /// - public DateTime LastAccessTime { + public DateTime LastAccessTime + { get { return _lastAccessTime; } - set { - if (!IsValidValue(value)) { + set + { + if (!IsValidValue(value)) + { throw new ArgumentOutOfRangeException(nameof(value)); } _lastAccessTime = value; @@ -422,16 +466,18 @@ public DateTime LastAccessTime { } #region Instance Fields - DateTime _lastAccessTime = DateTime.FromFileTimeUtc(0); - DateTime _lastModificationTime = DateTime.FromFileTimeUtc(0); - DateTime _createTime = DateTime.FromFileTimeUtc(0); - #endregion + + private DateTime _lastAccessTime = DateTime.FromFileTimeUtc(0); + private DateTime _lastModificationTime = DateTime.FromFileTimeUtc(0); + private DateTime _createTime = DateTime.FromFileTimeUtc(0); + + #endregion Instance Fields } /// /// A factory that creates tagged data instances. /// - interface ITaggedDataFactory + internal interface ITaggedDataFactory { /// /// Get data for a specific tag value. @@ -444,7 +490,7 @@ interface ITaggedDataFactory ITaggedData Create(short tag, byte[] data, int offset, int count); } - /// + /// /// /// A class to handle the extra data field for Zip entries /// @@ -458,6 +504,7 @@ interface ITaggedDataFactory sealed public class ZipExtraData : IDisposable { #region Constructors + /// /// Initialise a default instance. /// @@ -472,13 +519,17 @@ public ZipExtraData() /// The extra data. public ZipExtraData(byte[] data) { - if (data == null) { + if (data == null) + { _data = new byte[0]; - } else { + } + else + { _data = data; } } - #endregion + + #endregion Constructors /// /// Get the raw extra data value @@ -486,7 +537,8 @@ public ZipExtraData(byte[] data) /// Returns the raw byte[] extra data this instance represents. public byte[] GetEntryData() { - if (Length > ushort.MaxValue) { + if (Length > ushort.MaxValue) + { throw new ZipException("Data exceeds maximum length"); } @@ -498,7 +550,8 @@ public byte[] GetEntryData() /// public void Clear() { - if ((_data == null) || (_data.Length != 0)) { + if ((_data == null) || (_data.Length != 0)) + { _data = new byte[0]; } } @@ -506,7 +559,8 @@ public void Clear() /// /// Gets the current extra data length. /// - public int Length { + public int Length + { get { return _data.Length; } } @@ -518,7 +572,8 @@ public int Length { public Stream GetStreamForTag(int tag) { Stream result = null; - if (Find(tag)) { + if (Find(tag)) + { result = new MemoryStream(_data, _index, _readValueLength, false); } return result; @@ -545,7 +600,8 @@ public T GetData() /// Get the length of the last value found by /// /// This is only valid if has previously returned true. - public int ValueLength { + public int ValueLength + { get { return _readValueLength; } } @@ -555,17 +611,21 @@ public int ValueLength { /// This is only valid if has previously returned true. /// Initially the result will be the index of the first byte of actual data. The value is updated after calls to /// , and . - public int CurrentReadIndex { + public int CurrentReadIndex + { get { return _index; } } /// /// Get the number of bytes remaining to be read for the current value; /// - public int UnreadCount { - get { + public int UnreadCount + { + get + { if ((_readValueStart > _data.Length) || - (_readValueStart < 4)) { + (_readValueStart < 4)) + { throw new ZipException("Find must be called before calling a Read method"); } @@ -589,17 +649,20 @@ public bool Find(int headerID) // Trailing bytes that cant make up an entry (as there arent enough // bytes for a tag and length) are ignored! - while ((localTag != headerID) && (_index < _data.Length - 3)) { + while ((localTag != headerID) && (_index < _data.Length - 3)) + { localTag = ReadShortInternal(); localLength = ReadShortInternal(); - if (localTag != headerID) { + if (localTag != headerID) + { _index += localLength; } } bool result = (localTag == headerID) && ((_index + localLength) <= _data.Length); - if (result) { + if (result) + { _readValueStart = _index; _readValueLength = localLength; } @@ -613,7 +676,8 @@ public bool Find(int headerID) /// The value to add. public void AddEntry(ITaggedData taggedData) { - if (taggedData == null) { + if (taggedData == null) + { throw new ArgumentNullException(nameof(taggedData)); } AddEntry(taggedData.TagID, taggedData.GetData()); @@ -627,24 +691,28 @@ public void AddEntry(ITaggedData taggedData) /// If the ID already exists its contents are replaced. public void AddEntry(int headerID, byte[] fieldData) { - if ((headerID > ushort.MaxValue) || (headerID < 0)) { + if ((headerID > ushort.MaxValue) || (headerID < 0)) + { throw new ArgumentOutOfRangeException(nameof(headerID)); } int addLength = (fieldData == null) ? 0 : fieldData.Length; - if (addLength > ushort.MaxValue) { + if (addLength > ushort.MaxValue) + { throw new ArgumentOutOfRangeException(nameof(fieldData), "exceeds maximum length"); } // Test for new length before adjusting data. int newLength = _data.Length + addLength + 4; - if (Find(headerID)) { + if (Find(headerID)) + { newLength -= (ValueLength + 4); } - if (newLength > ushort.MaxValue) { + if (newLength > ushort.MaxValue) + { throw new ZipException("Data exceeds maximum length"); } @@ -656,7 +724,8 @@ public void AddEntry(int headerID, byte[] fieldData) _data = newData; SetShort(ref index, headerID); SetShort(ref index, addLength); - if (fieldData != null) { + if (fieldData != null) + { fieldData.CopyTo(newData, index); } } @@ -700,7 +769,8 @@ public void AddData(byte data) /// public void AddData(byte[] data) { - if (data == null) { + if (data == null) + { throw new ArgumentNullException(nameof(data)); } @@ -714,7 +784,8 @@ public void AddData(byte[] data) /// public void AddLeShort(int toAdd) { - unchecked { + unchecked + { _newEntry.WriteByte((byte)toAdd); _newEntry.WriteByte((byte)(toAdd >> 8)); } @@ -727,7 +798,8 @@ public void AddLeShort(int toAdd) /// public void AddLeInt(int toAdd) { - unchecked { + unchecked + { AddLeShort((short)toAdd); AddLeShort((short)(toAdd >> 16)); } @@ -740,7 +812,8 @@ public void AddLeInt(int toAdd) /// public void AddLeLong(long toAdd) { - unchecked { + unchecked + { AddLeInt((int)(toAdd & 0xffffffff)); AddLeInt((int)(toAdd >> 32)); } @@ -755,7 +828,8 @@ public bool Delete(int headerID) { bool result = false; - if (Find(headerID)) { + if (Find(headerID)) + { result = true; int trueStart = _readValueStart - 4; @@ -770,6 +844,7 @@ public bool Delete(int headerID) } #region Reading Support + /// /// Read a long in little endian form from the last found data value /// @@ -813,7 +888,8 @@ public int ReadShort() public int ReadByte() { int result = -1; - if ((_index < _data.Length) && (_readValueStart + _readValueLength > _index)) { + if ((_index < _data.Length) && (_readValueStart + _readValueLength > _index)) + { result = _data[_index]; _index += 1; } @@ -830,18 +906,21 @@ public void Skip(int amount) _index += amount; } - void ReadCheck(int length) + private void ReadCheck(int length) { if ((_readValueStart > _data.Length) || - (_readValueStart < 4)) { + (_readValueStart < 4)) + { throw new ZipException("Find must be called before calling a Read method"); } - if (_index > _readValueStart + _readValueLength - length) { + if (_index > _readValueStart + _readValueLength - length) + { throw new ZipException("End of extra data"); } - if (_index + length < 4) { + if (_index + length < 4) + { throw new ZipException("Cannot read before start of tag"); } } @@ -850,9 +929,10 @@ void ReadCheck(int length) /// Internal form of that reads data at any location. /// /// Returns the short value read. - int ReadShortInternal() + private int ReadShortInternal() { - if (_index > _data.Length - 2) { + if (_index > _data.Length - 2) + { throw new ZipException("End of extra data"); } @@ -861,14 +941,14 @@ int ReadShortInternal() return result; } - void SetShort(ref int index, int source) + private void SetShort(ref int index, int source) { _data[index] = (byte)source; _data[index + 1] = (byte)(source >> 8); index += 2; } - #endregion + #endregion Reading Support #region IDisposable Members @@ -877,20 +957,23 @@ void SetShort(ref int index, int source) /// public void Dispose() { - if (_newEntry != null) { + if (_newEntry != null) + { _newEntry.Dispose(); } } - #endregion + #endregion IDisposable Members #region Instance Fields - int _index; - int _readValueStart; - int _readValueLength; - MemoryStream _newEntry; - byte[] _data; - #endregion + private int _index; + private int _readValueStart; + private int _readValueLength; + + private MemoryStream _newEntry; + private byte[] _data; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs index d7298da57..778abfd15 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs @@ -1,25 +1,26 @@ +using ICSharpCode.SharpZipLib.Checksum; +using ICSharpCode.SharpZipLib.Core; +using ICSharpCode.SharpZipLib.Encryption; +using ICSharpCode.SharpZipLib.Zip.Compression; +using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using System; using System.Collections; +using System.Collections.Generic; using System.IO; -using System.Text; -using System.Globalization; using System.Security.Cryptography; -using ICSharpCode.SharpZipLib.Encryption; -using ICSharpCode.SharpZipLib.Core; -using ICSharpCode.SharpZipLib.Checksum; -using ICSharpCode.SharpZipLib.Zip.Compression.Streams; -using ICSharpCode.SharpZipLib.Zip.Compression; -using System.Collections.Generic; +using System.Text; namespace ICSharpCode.SharpZipLib.Zip { #region Keys Required Event Args + /// /// Arguments used with KeysRequiredEvent /// public class KeysRequiredEventArgs : EventArgs { #region Constructors + /// /// Initialise a new instance of /// @@ -40,32 +41,41 @@ public KeysRequiredEventArgs(string name, byte[] keyValue) key = keyValue; } - #endregion + #endregion Constructors + #region Properties + /// /// Gets the name of the file for which keys are required. /// - public string FileName { + public string FileName + { get { return fileName; } } /// /// Gets or sets the key value /// - public byte[] Key { + public byte[] Key + { get { return key; } set { key = value; } } - #endregion + + #endregion Properties #region Instance Fields - string fileName; - byte[] key; - #endregion + + private readonly string fileName; + private byte[] key; + + #endregion Instance Fields } - #endregion + + #endregion Keys Required Event Args #region Test Definitions + /// /// The strategy to apply to testing. /// @@ -75,6 +85,7 @@ public enum TestStrategy /// Find the first error only. /// FindFirstError, + /// /// Find all possible errors. /// @@ -125,6 +136,7 @@ public enum TestOperation public class TestStatus { #region Constructors + /// /// Initialise a new instance of /// @@ -133,54 +145,63 @@ public TestStatus(ZipFile file) { file_ = file; } - #endregion + + #endregion Constructors #region Properties /// /// Get the current in progress. /// - public TestOperation Operation { + public TestOperation Operation + { get { return operation_; } } /// /// Get the this status is applicable to. /// - public ZipFile File { + public ZipFile File + { get { return file_; } } /// /// Get the current/last entry tested. /// - public ZipEntry Entry { + public ZipEntry Entry + { get { return entry_; } } /// /// Get the number of errors detected so far. /// - public int ErrorCount { + public int ErrorCount + { get { return errorCount_; } } /// /// Get the number of bytes tested so far for the current entry. /// - public long BytesTested { + public long BytesTested + { get { return bytesTested_; } } /// /// Get a value indicating wether the last entry test was valid. /// - public bool EntryValid { + public bool EntryValid + { get { return entryValid_; } } - #endregion + + #endregion Properties #region Internal API + internal void AddError() { errorCount_++; @@ -203,16 +224,19 @@ internal void SetBytesTested(long value) { bytesTested_ = value; } - #endregion + + #endregion Internal API #region Instance Fields - ZipFile file_; - ZipEntry entry_; - bool entryValid_; - int errorCount_; - long bytesTested_; - TestOperation operation_; - #endregion + + private readonly ZipFile file_; + private ZipEntry entry_; + private bool entryValid_; + private int errorCount_; + private long bytesTested_; + private TestOperation operation_; + + #endregion Instance Fields } /// @@ -221,9 +245,11 @@ internal void SetBytesTested(long value) /// If the message is non-null an error has occured. If the message is null /// the operation as found in status has started. public delegate void ZipTestResultHandler(TestStatus status, string message); - #endregion + + #endregion Test Definitions #region Update Definitions + /// /// The possible ways of applying updates to an archive. /// @@ -233,21 +259,24 @@ public enum FileUpdateMode /// Perform all updates on temporary files ensuring that the original file is saved. /// Safe, + /// /// Update the archive directly, which is faster but less safe. /// Direct, } - #endregion + + #endregion Update Definitions #region ZipFile Class + /// /// This class represents a Zip archive. You can ask for the contained /// entries, or get an input stream for a file entry. The entry is /// automatically decompressed. - /// + /// /// You can also update the archive adding or deleting entries. - /// + /// /// This class is thread safe for input: You can open input streams for arbitrary /// entries in different threads. ///
@@ -259,9 +288,9 @@ public enum FileUpdateMode /// using System.Text; /// using System.Collections; /// using System.IO; - /// + /// /// using ICSharpCode.SharpZipLib.Zip; - /// + /// /// class MainClass /// { /// static public void Main(string[] args) @@ -305,9 +334,10 @@ KeysRequiredEventArgs e /// Handles getting of encryption keys when required. ///
/// The file for which encryption keys are required. - void OnKeysRequired(string fileName) + private void OnKeysRequired(string fileName) { - if (KeysRequired != null) { + if (KeysRequired != null) + { var krea = new KeysRequiredEventArgs(fileName, key); KeysRequired(this, krea); key = krea.Key; @@ -317,7 +347,8 @@ void OnKeysRequired(string fileName) /// /// Get/set the encryption key value. /// - byte[] Key { + private byte[] Key + { get { return key; } set { key = value; } } @@ -326,13 +357,18 @@ byte[] Key { /// Password to be used for encrypting/decrypting files. /// /// Set to null if no password is required. - public string Password { - set { - if (string.IsNullOrEmpty(value)) { + public string Password + { + set + { + if (string.IsNullOrEmpty(value)) + { key = null; - } else { + } + else + { rawPassword_ = value; - key = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(value)); + key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(value)); } } } @@ -340,12 +376,15 @@ public string Password { /// /// Get a value indicating wether encryption keys are currently available. /// - bool HaveKeys { + private bool HaveKeys + { get { return key != null; } } - #endregion + + #endregion KeyHandling #region Constructors + /// /// Opens a Zip file with the given name for reading. /// @@ -359,18 +398,17 @@ bool HaveKeys { /// public ZipFile(string name) { - if (name == null) { - throw new ArgumentNullException(nameof(name)); - } - - name_ = name; + name_ = name ?? throw new ArgumentNullException(nameof(name)); baseStream_ = File.Open(name, FileMode.Open, FileAccess.Read, FileShare.Read); isStreamOwner = true; - try { + try + { ReadEntries(); - } catch { + } + catch + { DisposeInternal(true); throw; } @@ -389,11 +427,13 @@ public ZipFile(string name) /// public ZipFile(FileStream file) { - if (file == null) { + if (file == null) + { throw new ArgumentNullException(nameof(file)); } - if (!file.CanSeek) { + if (!file.CanSeek) + { throw new ArgumentException("Stream is not seekable", nameof(file)); } @@ -401,9 +441,12 @@ public ZipFile(FileStream file) name_ = file.Name; isStreamOwner = true; - try { + try + { ReadEntries(); - } catch { + } + catch + { DisposeInternal(true); throw; } @@ -427,25 +470,33 @@ public ZipFile(FileStream file) /// public ZipFile(Stream stream) { - if (stream == null) { + if (stream == null) + { throw new ArgumentNullException(nameof(stream)); } - if (!stream.CanSeek) { + if (!stream.CanSeek) + { throw new ArgumentException("Stream is not seekable", nameof(stream)); } baseStream_ = stream; isStreamOwner = true; - if (baseStream_.Length > 0) { - try { + if (baseStream_.Length > 0) + { + try + { ReadEntries(); - } catch { + } + catch + { DisposeInternal(true); throw; } - } else { + } + else + { entries_ = new ZipEntry[0]; isNewArchive_ = true; } @@ -460,9 +511,10 @@ internal ZipFile() isNewArchive_ = true; } - #endregion + #endregion Constructors #region Destructors and Closing + /// /// Finalize this instance. /// @@ -484,9 +536,10 @@ public void Close() GC.SuppressFinalize(this); } - #endregion + #endregion Destructors and Closing #region Creators + /// /// Create a new whose data will be stored in a file. /// @@ -495,17 +548,19 @@ public void Close() /// is null public static ZipFile Create(string fileName) { - if (fileName == null) { + if (fileName == null) + { throw new ArgumentNullException(nameof(fileName)); } FileStream fs = File.Create(fileName); - var result = new ZipFile(); - result.name_ = fileName; - result.baseStream_ = fs; - result.isStreamOwner = true; - return result; + return new ZipFile + { + name_ = fileName, + baseStream_ = fs, + isStreamOwner = true + }; } /// @@ -517,26 +572,32 @@ public static ZipFile Create(string fileName) /// doesnt support writing. public static ZipFile Create(Stream outStream) { - if (outStream == null) { + if (outStream == null) + { throw new ArgumentNullException(nameof(outStream)); } - if (!outStream.CanWrite) { + if (!outStream.CanWrite) + { throw new ArgumentException("Stream is not writeable", nameof(outStream)); } - if (!outStream.CanSeek) { + if (!outStream.CanSeek) + { throw new ArgumentException("Stream is not seekable", nameof(outStream)); } - var result = new ZipFile(); - result.baseStream_ = outStream; + var result = new ZipFile + { + baseStream_ = outStream + }; return result; } - #endregion + #endregion Creators #region Properties + /// /// Get/set a flag indicating if the underlying stream is owned by the ZipFile instance. /// If the flag is true then the stream will be closed when Close is called. @@ -544,7 +605,8 @@ public static ZipFile Create(Stream outStream) /// /// The default value is true in all cases. /// - public bool IsStreamOwner { + public bool IsStreamOwner + { get { return isStreamOwner; } set { isStreamOwner = value; } } @@ -553,7 +615,8 @@ public bool IsStreamOwner { /// Get a value indicating wether /// this archive is embedded in another file or not. /// - public bool IsEmbeddedArchive { + public bool IsEmbeddedArchive + { // Not strictly correct in all circumstances currently get { return offsetOfFirstEntry > 0; } } @@ -561,21 +624,24 @@ public bool IsEmbeddedArchive { /// /// Get a value indicating that this archive is a new one. /// - public bool IsNewArchive { + public bool IsNewArchive + { get { return isNewArchive_; } } /// /// Gets the comment for the zip file. /// - public string ZipFileComment { + public string ZipFileComment + { get { return comment_; } } /// /// Gets the name of this zip file. /// - public string Name { + public string Name + { get { return name_; } } @@ -586,8 +652,10 @@ public string Name { /// The Zip file has been closed. /// [Obsolete("Use the Count property instead")] - public int Size { - get { + public int Size + { + get + { return entries_.Length; } } @@ -595,8 +663,10 @@ public int Size { /// /// Get the number of entries contained in this . /// - public long Count { - get { + public long Count + { + get + { return entries_.Length; } } @@ -605,15 +675,18 @@ public long Count { /// Indexer property for ZipEntries /// [System.Runtime.CompilerServices.IndexerNameAttribute("EntryByIndex")] - public ZipEntry this[int index] { - get { + public ZipEntry this[int index] + { + get + { return (ZipEntry)entries_[index].Clone(); } } - #endregion + #endregion Properties #region Input Handling + /// /// Gets an enumerator for the Zip entries in this Zip file. /// @@ -623,7 +696,8 @@ public ZipEntry this[int index] { /// public IEnumerator GetEnumerator() { - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } @@ -641,13 +715,16 @@ public IEnumerator GetEnumerator() /// public int FindEntry(string name, bool ignoreCase) { - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } // TODO: This will be slow as the next ice age for huge archives! - for (int i = 0; i < entries_.Length; i++) { - if (string.Compare(name, entries_[i].Name, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0) { + for (int i = 0; i < entries_.Length; i++) + { + if (string.Compare(name, entries_[i].Name, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0) + { return i; } } @@ -669,7 +746,8 @@ public int FindEntry(string name, bool ignoreCase) /// public ZipEntry GetEntry(string name) { - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } @@ -694,18 +772,22 @@ public ZipEntry GetEntry(string name) /// public Stream GetInputStream(ZipEntry entry) { - if (entry == null) { + if (entry == null) + { throw new ArgumentNullException(nameof(entry)); } - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } long index = entry.ZipFileIndex; - if ((index < 0) || (index >= entries_.Length) || (entries_[index].Name != entry.Name)) { + if ((index < 0) || (index >= entries_.Length) || (entries_[index].Name != entry.Name)) + { index = FindEntry(entry.Name, true); - if (index < 0) { + if (index < 0) + { throw new ZipException("Entry cannot be found"); } } @@ -730,7 +812,8 @@ public Stream GetInputStream(ZipEntry entry) /// public Stream GetInputStream(long entryIndex) { - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } @@ -738,14 +821,17 @@ public Stream GetInputStream(long entryIndex) CompressionMethod method = entries_[entryIndex].CompressionMethod; Stream result = new PartialInputStream(this, start, entries_[entryIndex].CompressedSize); - if (entries_[entryIndex].IsCrypted == true) { + if (entries_[entryIndex].IsCrypted == true) + { result = CreateAndInitDecryptionStream(result, entries_[entryIndex]); - if (result == null) { + if (result == null) + { throw new ZipException("Unable to decrypt this entry"); } } - switch (method) { + switch (method) + { case CompressionMethod.Stored: // read as is. break; @@ -762,9 +848,10 @@ public Stream GetInputStream(long entryIndex) return result; } - #endregion + #endregion Input Handling #region Archive Testing + /// /// Test an archive for integrity/validity /// @@ -786,60 +873,66 @@ public bool TestArchive(bool testData) /// The object has already been closed. public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandler resultHandler) { - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } var status = new TestStatus(this); - if (resultHandler != null) { - resultHandler(status, null); - } + resultHandler?.Invoke(status, null); HeaderTest test = testData ? (HeaderTest.Header | HeaderTest.Extract) : HeaderTest.Header; bool testing = true; - try { + try + { int entryIndex = 0; - while (testing && (entryIndex < Count)) { - if (resultHandler != null) { + while (testing && (entryIndex < Count)) + { + if (resultHandler != null) + { status.SetEntry(this[entryIndex]); status.SetOperation(TestOperation.EntryHeader); resultHandler(status, null); } - try { + try + { TestLocalHeader(this[entryIndex], test); - } catch (ZipException ex) { + } + catch (ZipException ex) + { status.AddError(); - if (resultHandler != null) { - resultHandler(status, - string.Format("Exception during test - '{0}'", ex.Message)); - } + resultHandler?.Invoke(status, $"Exception during test - '{ex.Message}'"); testing &= strategy != TestStrategy.FindFirstError; } - if (testing && testData && this[entryIndex].IsFile) { - if (resultHandler != null) { + if (testing && testData && this[entryIndex].IsFile) + { + if (resultHandler != null) + { status.SetOperation(TestOperation.EntryData); resultHandler(status, null); } var crc = new Crc32(); - using (Stream entryStream = this.GetInputStream(this[entryIndex])) { - + using (Stream entryStream = this.GetInputStream(this[entryIndex])) + { byte[] buffer = new byte[4096]; long totalBytes = 0; int bytesRead; - while ((bytesRead = entryStream.Read(buffer, 0, buffer.Length)) > 0) { + while ((bytesRead = entryStream.Read(buffer, 0, buffer.Length)) > 0) + { crc.Update(new ArraySegment(buffer, 0, bytesRead)); - if (resultHandler != null) { + if (resultHandler != null) + { totalBytes += bytesRead; status.SetBytesTested(totalBytes); resultHandler(status, null); @@ -847,35 +940,39 @@ public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandl } } - if (this[entryIndex].Crc != crc.Value) { + if (this[entryIndex].Crc != crc.Value) + { status.AddError(); - if (resultHandler != null) { - resultHandler(status, "CRC mismatch"); - } + resultHandler?.Invoke(status, "CRC mismatch"); testing &= strategy != TestStrategy.FindFirstError; } - if ((this[entryIndex].Flags & (int)GeneralBitFlags.Descriptor) != 0) { + if ((this[entryIndex].Flags & (int)GeneralBitFlags.Descriptor) != 0) + { var helper = new ZipHelperStream(baseStream_); var data = new DescriptorData(); helper.ReadDataDescriptor(this[entryIndex].LocalHeaderRequiresZip64, data); - if (this[entryIndex].Crc != data.Crc) { + if (this[entryIndex].Crc != data.Crc) + { status.AddError(); } - if (this[entryIndex].CompressedSize != data.CompressedSize) { + if (this[entryIndex].CompressedSize != data.CompressedSize) + { status.AddError(); } - if (this[entryIndex].Size != data.Size) { + if (this[entryIndex].Size != data.Size) + { status.AddError(); } } } - if (resultHandler != null) { + if (resultHandler != null) + { status.SetOperation(TestOperation.EntryComplete); resultHandler(status, null); } @@ -883,22 +980,24 @@ public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandl entryIndex += 1; } - if (resultHandler != null) { + if (resultHandler != null) + { status.SetOperation(TestOperation.MiscellaneousTests); resultHandler(status, null); } // TODO: the 'Corrina Johns' test where local headers are missing from // the central directory. They are therefore invisible to many archivers. - } catch (Exception ex) { + } + catch (Exception ex) + { status.AddError(); - if (resultHandler != null) { - resultHandler(status, string.Format("Exception during test - '{0}'", ex.Message)); - } + resultHandler?.Invoke(status, $"Exception during test - '{ex.Message}'"); } - if (resultHandler != null) { + if (resultHandler != null) + { status.SetOperation(TestOperation.Complete); status.SetEntry(null); resultHandler(status, null); @@ -908,7 +1007,7 @@ public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandl } [Flags] - enum HeaderTest + private enum HeaderTest { Extract = 0x01, // Check that this header represents an entry whose data can be extracted Header = 0x02, // Check that this header contents are valid @@ -922,14 +1021,16 @@ enum HeaderTest /// /// The type of tests to carry out. /// The offset of the entries data in the file - long TestLocalHeader(ZipEntry entry, HeaderTest tests) + private long TestLocalHeader(ZipEntry entry, HeaderTest tests) { - lock (baseStream_) { + lock (baseStream_) + { bool testHeader = (tests & HeaderTest.Header) != 0; bool testData = (tests & HeaderTest.Extract) != 0; baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin); - if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) { + if ((int)ReadLEUint() != ZipConstants.LocalHeaderSignature) + { throw new ZipException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset)); } @@ -953,49 +1054,62 @@ long TestLocalHeader(ZipEntry entry, HeaderTest tests) var localExtraData = new ZipExtraData(extraData); // Extra data / zip64 checks - if (localExtraData.Find(1)) { + if (localExtraData.Find(1)) + { // 2010-03-04 Forum 10512: removed checks for version >= ZipConstants.VersionZip64 // and size or compressedSize = MaxValue, due to rogue creators. size = localExtraData.ReadLong(); compressedSize = localExtraData.ReadLong(); - if ((localFlags & (int)GeneralBitFlags.Descriptor) != 0) { + if ((localFlags & (int)GeneralBitFlags.Descriptor) != 0) + { // These may be valid if patched later - if ((size != -1) && (size != entry.Size)) { + if ((size != -1) && (size != entry.Size)) + { throw new ZipException("Size invalid for descriptor"); } - if ((compressedSize != -1) && (compressedSize != entry.CompressedSize)) { + if ((compressedSize != -1) && (compressedSize != entry.CompressedSize)) + { throw new ZipException("Compressed size invalid for descriptor"); } } - } else { + } + else + { // No zip64 extra data but entry requires it. if ((extractVersion >= ZipConstants.VersionZip64) && - (((uint)size == uint.MaxValue) || ((uint)compressedSize == uint.MaxValue))) { + (((uint)size == uint.MaxValue) || ((uint)compressedSize == uint.MaxValue))) + { throw new ZipException("Required Zip64 extended information missing"); } } - if (testData) { - if (entry.IsFile) { - if (!entry.IsCompressionMethodSupported()) { + if (testData) + { + if (entry.IsFile) + { + if (!entry.IsCompressionMethodSupported()) + { throw new ZipException("Compression method not supported"); } if ((extractVersion > ZipConstants.VersionMadeBy) - || ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64))) { + || ((extractVersion > 20) && (extractVersion < ZipConstants.VersionZip64))) + { throw new ZipException(string.Format("Version required to extract this entry not supported ({0})", extractVersion)); } - if ((localFlags & (int)(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0) { + if ((localFlags & (int)(GeneralBitFlags.Patched | GeneralBitFlags.StrongEncryption | GeneralBitFlags.EnhancedCompress | GeneralBitFlags.HeaderMasked)) != 0) + { throw new ZipException("The library does not support the zip version required to extract this entry"); } } } - if (testHeader) { + if (testHeader) + { if ((extractVersion <= 63) && // Ignore later versions as we dont know about them.. (extractVersion != 10) && (extractVersion != 11) && @@ -1011,104 +1125,130 @@ long TestLocalHeader(ZipEntry entry, HeaderTest tests) (extractVersion != 61) && (extractVersion != 62) && (extractVersion != 63) - ) { + ) + { throw new ZipException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion)); } // Local entry flags dont have reserved bit set on. - if ((localFlags & (int)(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0) { + if ((localFlags & (int)(GeneralBitFlags.ReservedPKware4 | GeneralBitFlags.ReservedPkware14 | GeneralBitFlags.ReservedPkware15)) != 0) + { throw new ZipException("Reserved bit flags cannot be set."); } // Encryption requires extract version >= 20 - if (((localFlags & (int)GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20)) { + if (((localFlags & (int)GeneralBitFlags.Encrypted) != 0) && (extractVersion < 20)) + { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } // Strong encryption requires encryption flag to be set and extract version >= 50. - if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) { - if ((localFlags & (int)GeneralBitFlags.Encrypted) == 0) { + if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) + { + if ((localFlags & (int)GeneralBitFlags.Encrypted) == 0) + { throw new ZipException("Strong encryption flag set but encryption flag is not set"); } - if (extractVersion < 50) { + if (extractVersion < 50) + { throw new ZipException(string.Format("Version required to extract this entry is too low for encryption ({0})", extractVersion)); } } // Patched entries require extract version >= 27 - if (((localFlags & (int)GeneralBitFlags.Patched) != 0) && (extractVersion < 27)) { + if (((localFlags & (int)GeneralBitFlags.Patched) != 0) && (extractVersion < 27)) + { throw new ZipException(string.Format("Patched data requires higher version than ({0})", extractVersion)); } // Central header flags match local entry flags. - if (localFlags != entry.Flags) { + if (localFlags != entry.Flags) + { throw new ZipException("Central header/local header flags mismatch"); } // Central header compression method matches local entry - if (entry.CompressionMethod != (CompressionMethod)compressionMethod) { + if (entry.CompressionMethod != (CompressionMethod)compressionMethod) + { throw new ZipException("Central header/local header compression method mismatch"); } - if (entry.Version != extractVersion) { + if (entry.Version != extractVersion) + { throw new ZipException("Extract version mismatch"); } // Strong encryption and extract version match - if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) { - if (extractVersion < 62) { + if ((localFlags & (int)GeneralBitFlags.StrongEncryption) != 0) + { + if (extractVersion < 62) + { throw new ZipException("Strong encryption flag set but version not high enough"); } } - if ((localFlags & (int)GeneralBitFlags.HeaderMasked) != 0) { - if ((fileTime != 0) || (fileDate != 0)) { + if ((localFlags & (int)GeneralBitFlags.HeaderMasked) != 0) + { + if ((fileTime != 0) || (fileDate != 0)) + { throw new ZipException("Header masked set but date/time values non-zero"); } } - if ((localFlags & (int)GeneralBitFlags.Descriptor) == 0) { - if (crcValue != (uint)entry.Crc) { + if ((localFlags & (int)GeneralBitFlags.Descriptor) == 0) + { + if (crcValue != (uint)entry.Crc) + { throw new ZipException("Central header/local header crc mismatch"); } } // Crc valid for empty entry. // This will also apply to streamed entries where size isnt known and the header cant be patched - if ((size == 0) && (compressedSize == 0)) { - if (crcValue != 0) { + if ((size == 0) && (compressedSize == 0)) + { + if (crcValue != 0) + { throw new ZipException("Invalid CRC for empty entry"); } } // TODO: make test more correct... can't compare lengths as was done originally as this can fail for MBCS strings // Assuming a code page at this point is not valid? Best is to store the name length in the ZipEntry probably - if (entry.Name.Length > storedNameLength) { + if (entry.Name.Length > storedNameLength) + { throw new ZipException("File name length mismatch"); } // Name data has already been read convert it and compare. - string localName = ZipConstants.ConvertToStringExt(localFlags, nameData); + string localName = ZipStrings.ConvertToStringExt(localFlags, nameData); // Central directory and local entry name match - if (localName != entry.Name) { + if (localName != entry.Name) + { throw new ZipException("Central header and local header file name mismatch"); } // Directories have zero actual size but can have compressed size - if (entry.IsDirectory) { - if (size > 0) { + if (entry.IsDirectory) + { + if (size > 0) + { throw new ZipException("Directory cannot have size"); } // There may be other cases where the compressed size can be greater than this? // If so until details are known we will be strict. - if (entry.IsCrypted) { - if (compressedSize > ZipConstants.CryptoHeaderSize + 2) { + if (entry.IsCrypted) + { + if (compressedSize > ZipConstants.CryptoHeaderSize + 2) + { throw new ZipException("Directory compressed size invalid"); } - } else if (compressedSize > 2) { + } + else if (compressedSize > 2) + { // When not compressed the directory size can validly be 2 bytes // if the true size wasnt known when data was originally being written. // NOTE: Versions of the library 0.85.4 and earlier always added 2 bytes @@ -1116,7 +1256,8 @@ long TestLocalHeader(ZipEntry entry, HeaderTest tests) } } - if (!ZipNameTransform.IsValidName(localName, true)) { + if (!ZipNameTransform.IsValidName(localName, true)) + { throw new ZipException("Name is invalid"); } } @@ -1126,17 +1267,19 @@ long TestLocalHeader(ZipEntry entry, HeaderTest tests) // Size can be verified only if it is known in the local header. // it will always be known in the central header. if (((localFlags & (int)GeneralBitFlags.Descriptor) == 0) || - ((size > 0 || compressedSize > 0) && entry.Size > 0)) { - + ((size > 0 || compressedSize > 0) && entry.Size > 0)) + { if ((size != 0) - && (size != entry.Size)) { + && (size != entry.Size)) + { throw new ZipException( string.Format("Size mismatch between central header({0}) and local header({1})", entry.Size, size)); } if ((compressedSize != 0) - && (compressedSize != entry.CompressedSize && compressedSize != 0xFFFFFFFF && compressedSize != -1)) { + && (compressedSize != entry.CompressedSize && compressedSize != 0xFFFFFFFF && compressedSize != -1)) + { throw new ZipException( string.Format("Compressed size mismatch between central header({0}) and local header({1})", entry.CompressedSize, compressedSize)); @@ -1148,16 +1291,16 @@ long TestLocalHeader(ZipEntry entry, HeaderTest tests) } } - #endregion + #endregion Archive Testing #region Updating - const int DefaultBufferSize = 4096; + private const int DefaultBufferSize = 4096; /// /// The kind of update to apply. /// - enum UpdateCommand + private enum UpdateCommand { Copy, // Copy original file contents. Modify, // Change encryption, compression, attributes, name, time etc, of an existing file. @@ -1165,15 +1308,19 @@ enum UpdateCommand } #region Properties + /// /// Get / set the to apply to names when updating. /// - public INameTransform NameTransform { - get { + public INameTransform NameTransform + { + get + { return updateEntryFactory_.NameTransform; } - set { + set + { updateEntryFactory_.NameTransform = value; } } @@ -1182,15 +1329,21 @@ public INameTransform NameTransform { /// Get/set the used to generate values /// during updates. /// - public IEntryFactory EntryFactory { - get { + public IEntryFactory EntryFactory + { + get + { return updateEntryFactory_; } - set { - if (value == null) { + set + { + if (value == null) + { updateEntryFactory_ = new ZipEntryFactory(); - } else { + } + else + { updateEntryFactory_ = value; } } @@ -1199,14 +1352,18 @@ public IEntryFactory EntryFactory { /// /// Get /set the buffer size to be used when updating this zip file. /// - public int BufferSize { + public int BufferSize + { get { return bufferSize_; } - set { - if (value < 1024) { + set + { + if (value < 1024) + { throw new ArgumentOutOfRangeException(nameof(value), "cannot be below 1024"); } - if (bufferSize_ != value) { + if (bufferSize_ != value) + { bufferSize_ = value; copyBuffer_ = null; } @@ -1216,23 +1373,26 @@ public int BufferSize { /// /// Get a value indicating an update has been started. /// - public bool IsUpdating { + public bool IsUpdating + { get { return updates_ != null; } } /// /// Get / set a value indicating how Zip64 Extension usage is determined when adding entries. /// - public UseZip64 UseZip64 { + public UseZip64 UseZip64 + { get { return useZip64_; } set { useZip64_ = value; } } - #endregion + #endregion Properties #region Immediate updating + // TBD: Direct form of updating - // + // // public void Update(IEntryMatcher deleteMatcher) // { // } @@ -1240,9 +1400,11 @@ public UseZip64 UseZip64 { // public void Update(IScanner addScanner) // { // } - #endregion + + #endregion Immediate updating #region Deferred Updating + /// /// Begin updating this archive. /// @@ -1253,31 +1415,26 @@ public UseZip64 UseZip64 { /// ZipFile has been closed. public void BeginUpdate(IArchiveStorage archiveStorage, IDynamicDataSource dataSource) { - if (archiveStorage == null) { - throw new ArgumentNullException(nameof(archiveStorage)); - } - - if (dataSource == null) { - throw new ArgumentNullException(nameof(dataSource)); - } - - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } - if (IsEmbeddedArchive) { + if (IsEmbeddedArchive) + { throw new ZipException("Cannot update embedded/SFX archives"); } - archiveStorage_ = archiveStorage; - updateDataSource_ = dataSource; + archiveStorage_ = archiveStorage ?? throw new ArgumentNullException(nameof(archiveStorage)); + updateDataSource_ = dataSource ?? throw new ArgumentNullException(nameof(dataSource)); // NOTE: the baseStream_ may not currently support writing or seeking. updateIndex_ = new Dictionary(); updates_ = new List(entries_.Length); - foreach (ZipEntry entry in entries_) { + foreach (ZipEntry entry in entries_) + { int index = updates_.Count; updates_.Add(new ZipUpdate(entry)); updateIndex_.Add(entry.Name, index); @@ -1287,7 +1444,8 @@ public void BeginUpdate(IArchiveStorage archiveStorage, IDynamicDataSource dataS updates_.Sort(new UpdateComparer()); int idx = 0; - foreach (ZipUpdate update in updates_) { + foreach (ZipUpdate update in updates_) + { //If last entry, there is no next entry offset to use if (idx == updates_.Count - 1) break; @@ -1319,9 +1477,12 @@ public void BeginUpdate(IArchiveStorage archiveStorage) /// public void BeginUpdate() { - if (Name == null) { + if (Name == null) + { BeginUpdate(new MemoryArchiveStorage(), new DynamicDiskDataSource()); - } else { + } + else + { BeginUpdate(new DiskArchiveStorage(this), new DynamicDiskDataSource()); } } @@ -1334,31 +1495,41 @@ public void BeginUpdate() /// ZipFile has been closed. public void CommitUpdate() { - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } CheckUpdating(); - try { + try + { updateIndex_.Clear(); updateIndex_ = null; - if (contentsEdited_) { + if (contentsEdited_) + { RunUpdates(); - } else if (commentEdited_) { + } + else if (commentEdited_) + { UpdateCommentOnly(); - } else { + } + else + { // Create an empty archive if none existed originally. - if (entries_.Length == 0) { - byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipConstants.ConvertToArray(comment_); - using (ZipHelperStream zhs = new ZipHelperStream(baseStream_)) { + if (entries_.Length == 0) + { + byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipStrings.ConvertToArray(comment_); + using (ZipHelperStream zhs = new ZipHelperStream(baseStream_)) + { zhs.WriteEndOfCentralDirectory(0, 0, 0, theComment); } } } - - } finally { + } + finally + { PostUpdateCleanup(); } } @@ -1380,7 +1551,8 @@ public void AbortUpdate() /// ZipFile has been closed. public void SetComment(string comment) { - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } @@ -1388,7 +1560,8 @@ public void SetComment(string comment) newComment_ = new ZipString(comment); - if (newComment_.RawLength > 0xffff) { + if (newComment_.RawLength > 0xffff) + { newComment_ = null; throw new ZipException("Comment length exceeds maximum - 65535"); } @@ -1398,24 +1571,28 @@ public void SetComment(string comment) commentEdited_ = true; } - #endregion + #endregion Deferred Updating #region Adding Entries - void AddUpdate(ZipUpdate update) + private void AddUpdate(ZipUpdate update) { contentsEdited_ = true; int index = FindExistingUpdate(update.Entry.Name); - if (index >= 0) { - if (updates_[index] == null) { + if (index >= 0) + { + if (updates_[index] == null) + { updateCount_ += 1; } // Direct replacement is faster than delete and add. updates_[index] = update; - } else { + } + else + { index = updates_.Count; updates_.Add(update); updateCount_ += 1; @@ -1434,15 +1611,18 @@ void AddUpdate(ZipUpdate update) /// Compression method is not supported. public void Add(string fileName, CompressionMethod compressionMethod, bool useUnicodeText) { - if (fileName == null) { + if (fileName == null) + { throw new ArgumentNullException(nameof(fileName)); } - if (isDisposed_) { + if (isDisposed_) + { throw new ObjectDisposedException("ZipFile"); } - if (!ZipEntry.IsCompressionMethodSupported(compressionMethod)) { + if (!ZipEntry.IsCompressionMethodSupported(compressionMethod)) + { throw new ArgumentOutOfRangeException(nameof(compressionMethod)); } @@ -1465,11 +1645,13 @@ public void Add(string fileName, CompressionMethod compressionMethod, bool useUn /// The compression method is not supported. public void Add(string fileName, CompressionMethod compressionMethod) { - if (fileName == null) { + if (fileName == null) + { throw new ArgumentNullException(nameof(fileName)); } - if (!ZipEntry.IsCompressionMethodSupported(compressionMethod)) { + if (!ZipEntry.IsCompressionMethodSupported(compressionMethod)) + { throw new ArgumentOutOfRangeException(nameof(compressionMethod)); } @@ -1488,7 +1670,8 @@ public void Add(string fileName, CompressionMethod compressionMethod) /// Argument supplied is null. public void Add(string fileName) { - if (fileName == null) { + if (fileName == null) + { throw new ArgumentNullException(nameof(fileName)); } @@ -1504,11 +1687,13 @@ public void Add(string fileName) /// Argument supplied is null. public void Add(string fileName, string entryName) { - if (fileName == null) { + if (fileName == null) + { throw new ArgumentNullException(nameof(fileName)); } - if (entryName == null) { + if (entryName == null) + { throw new ArgumentNullException(nameof(entryName)); } @@ -1516,7 +1701,6 @@ public void Add(string fileName, string entryName) AddUpdate(new ZipUpdate(fileName, EntryFactory.MakeFileEntry(fileName, entryName, true))); } - /// /// Add a file entry with data. /// @@ -1524,11 +1708,13 @@ public void Add(string fileName, string entryName) /// The name to give to the entry. public void Add(IStaticDataSource dataSource, string entryName) { - if (dataSource == null) { + if (dataSource == null) + { throw new ArgumentNullException(nameof(dataSource)); } - if (entryName == null) { + if (entryName == null) + { throw new ArgumentNullException(nameof(entryName)); } @@ -1544,11 +1730,13 @@ public void Add(IStaticDataSource dataSource, string entryName) /// The compression method to use. public void Add(IStaticDataSource dataSource, string entryName, CompressionMethod compressionMethod) { - if (dataSource == null) { + if (dataSource == null) + { throw new ArgumentNullException(nameof(dataSource)); } - if (entryName == null) { + if (entryName == null) + { throw new ArgumentNullException(nameof(entryName)); } @@ -1569,11 +1757,13 @@ public void Add(IStaticDataSource dataSource, string entryName, CompressionMetho /// Ensure Unicode text is used for name and comments for this entry. public void Add(IStaticDataSource dataSource, string entryName, CompressionMethod compressionMethod, bool useUnicodeText) { - if (dataSource == null) { + if (dataSource == null) + { throw new ArgumentNullException(nameof(dataSource)); } - if (entryName == null) { + if (entryName == null) + { throw new ArgumentNullException(nameof(entryName)); } @@ -1593,13 +1783,15 @@ public void Add(IStaticDataSource dataSource, string entryName, CompressionMetho /// This can be used to add directories, volume labels, or empty file entries. public void Add(ZipEntry entry) { - if (entry == null) { + if (entry == null) + { throw new ArgumentNullException(nameof(entry)); } CheckUpdating(); - if ((entry.Size != 0) || (entry.CompressedSize != 0)) { + if ((entry.Size != 0) || (entry.CompressedSize != 0)) + { throw new ZipException("Entry cannot have any data"); } @@ -1612,7 +1804,8 @@ public void Add(ZipEntry entry) /// The directory to add. public void AddDirectory(string directoryName) { - if (directoryName == null) { + if (directoryName == null) + { throw new ArgumentNullException(nameof(directoryName)); } @@ -1622,9 +1815,10 @@ public void AddDirectory(string directoryName) AddUpdate(new ZipUpdate(UpdateCommand.Add, dirEntry)); } - #endregion + #endregion Adding Entries #region Modifying Entries + /* Modify not yet ready for public consumption. Direct modification of an entry should not overwrite original data before its read. Safe mode is trivial in this sense. @@ -1643,9 +1837,11 @@ public void Modify(ZipEntry original, ZipEntry updated) updates_.Add(new ZipUpdate(original, updated)); } */ - #endregion + + #endregion Modifying Entries #region Deleting Entries + /// /// Delete an entry by name /// @@ -1653,7 +1849,8 @@ public void Modify(ZipEntry original, ZipEntry updated) /// True if the entry was found and deleted; false otherwise. public bool Delete(string fileName) { - if (fileName == null) { + if (fileName == null) + { throw new ArgumentNullException(nameof(fileName)); } @@ -1661,12 +1858,15 @@ public bool Delete(string fileName) bool result = false; int index = FindExistingUpdate(fileName); - if ((index >= 0) && (updates_[index] != null)) { + if ((index >= 0) && (updates_[index] != null)) + { result = true; contentsEdited_ = true; updates_[index] = null; updateCount_ -= 1; - } else { + } + else + { throw new ZipException("Cannot find entry to delete"); } return result; @@ -1678,28 +1878,33 @@ public bool Delete(string fileName) /// The entry to delete. public void Delete(ZipEntry entry) { - if (entry == null) { + if (entry == null) + { throw new ArgumentNullException(nameof(entry)); } CheckUpdating(); int index = FindExistingUpdate(entry); - if (index >= 0) { + if (index >= 0) + { contentsEdited_ = true; updates_[index] = null; updateCount_ -= 1; - } else { + } + else + { throw new ZipException("Cannot find entry to delete"); } } - #endregion + #endregion Deleting Entries #region Update Support #region Writing Values/Headers - void WriteLEShort(int value) + + private void WriteLEShort(int value) { baseStream_.WriteByte((byte)(value & 0xff)); baseStream_.WriteByte((byte)((value >> 8) & 0xff)); @@ -1708,7 +1913,7 @@ void WriteLEShort(int value) /// /// Write an unsigned short in little endian byte order. /// - void WriteLEUshort(ushort value) + private void WriteLEUshort(ushort value) { baseStream_.WriteByte((byte)(value & 0xff)); baseStream_.WriteByte((byte)(value >> 8)); @@ -1717,7 +1922,7 @@ void WriteLEUshort(ushort value) /// /// Write an int in little endian byte order. /// - void WriteLEInt(int value) + private void WriteLEInt(int value) { WriteLEShort(value & 0xffff); WriteLEShort(value >> 16); @@ -1726,7 +1931,7 @@ void WriteLEInt(int value) /// /// Write an unsigned int in little endian byte order. /// - void WriteLEUint(uint value) + private void WriteLEUint(uint value) { WriteLEUshort((ushort)(value & 0xffff)); WriteLEUshort((ushort)(value >> 16)); @@ -1735,19 +1940,19 @@ void WriteLEUint(uint value) /// /// Write a long in little endian byte order. /// - void WriteLeLong(long value) + private void WriteLeLong(long value) { WriteLEInt((int)(value & 0xffffffff)); WriteLEInt((int)(value >> 32)); } - void WriteLEUlong(ulong value) + private void WriteLEUlong(ulong value) { WriteLEUint((uint)(value & 0xffffffff)); WriteLEUint((uint)(value >> 32)); } - void WriteLocalEntryHeader(ZipUpdate update) + private void WriteLocalEntryHeader(ZipUpdate update) { ZipEntry entry = update.OutEntry; @@ -1755,30 +1960,41 @@ void WriteLocalEntryHeader(ZipUpdate update) entry.Offset = baseStream_.Position; // TODO: Need to clear any entry flags that dont make sense or throw an exception here. - if (update.Command != UpdateCommand.Copy) { - if (entry.CompressionMethod == CompressionMethod.Deflated) { - if (entry.Size == 0) { + if (update.Command != UpdateCommand.Copy) + { + if (entry.CompressionMethod == CompressionMethod.Deflated) + { + if (entry.Size == 0) + { // No need to compress - no data. entry.CompressedSize = entry.Size; entry.Crc = 0; entry.CompressionMethod = CompressionMethod.Stored; } - } else if (entry.CompressionMethod == CompressionMethod.Stored) { + } + else if (entry.CompressionMethod == CompressionMethod.Stored) + { entry.Flags &= ~(int)GeneralBitFlags.Descriptor; } - if (HaveKeys) { + if (HaveKeys) + { entry.IsCrypted = true; - if (entry.Crc < 0) { + if (entry.Crc < 0) + { entry.Flags |= (int)GeneralBitFlags.Descriptor; } - } else { + } + else + { entry.IsCrypted = false; } - switch (useZip64_) { + switch (useZip64_) + { case UseZip64.Dynamic: - if (entry.Size < 0) { + if (entry.Size < 0) + { entry.ForceZip64(); } break; @@ -1802,19 +2018,26 @@ void WriteLocalEntryHeader(ZipUpdate update) WriteLEShort((byte)entry.CompressionMethod); WriteLEInt((int)entry.DosTime); - if (!entry.HasCrc) { + if (!entry.HasCrc) + { // Note patch address for updating CRC later. update.CrcPatchOffset = baseStream_.Position; WriteLEInt((int)0); - } else { + } + else + { WriteLEInt(unchecked((int)entry.Crc)); } - if (entry.LocalHeaderRequiresZip64) { + if (entry.LocalHeaderRequiresZip64) + { WriteLEInt(-1); WriteLEInt(-1); - } else { - if ((entry.CompressedSize < 0) || (entry.Size < 0)) { + } + else + { + if ((entry.CompressedSize < 0) || (entry.Size < 0)) + { update.SizePatchOffset = baseStream_.Position; } @@ -1822,15 +2045,17 @@ void WriteLocalEntryHeader(ZipUpdate update) WriteLEInt((int)entry.Size); } - byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); + byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name); - if (name.Length > 0xFFFF) { + if (name.Length > 0xFFFF) + { throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); - if (entry.LocalHeaderRequiresZip64) { + if (entry.LocalHeaderRequiresZip64) + { ed.StartNewEntry(); // Local entry header always includes size and compressed size. @@ -1838,7 +2063,9 @@ void WriteLocalEntryHeader(ZipUpdate update) ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); ed.AddNewEntry(1); - } else { + } + else + { ed.Delete(1); } @@ -1847,34 +2074,41 @@ void WriteLocalEntryHeader(ZipUpdate update) WriteLEShort(name.Length); WriteLEShort(entry.ExtraData.Length); - if (name.Length > 0) { + if (name.Length > 0) + { baseStream_.Write(name, 0, name.Length); } - if (entry.LocalHeaderRequiresZip64) { - if (!ed.Find(1)) { + if (entry.LocalHeaderRequiresZip64) + { + if (!ed.Find(1)) + { throw new ZipException("Internal error cannot find extra data"); } update.SizePatchOffset = baseStream_.Position + ed.CurrentReadIndex; } - if (entry.ExtraData.Length > 0) { + if (entry.ExtraData.Length > 0) + { baseStream_.Write(entry.ExtraData, 0, entry.ExtraData.Length); } } - int WriteCentralDirectoryHeader(ZipEntry entry) + private int WriteCentralDirectoryHeader(ZipEntry entry) { - if (entry.CompressedSize < 0) { + if (entry.CompressedSize < 0) + { throw new ZipException("Attempt to write central directory entry with unknown csize"); } - if (entry.Size < 0) { + if (entry.Size < 0) + { throw new ZipException("Attempt to write central directory entry with unknown size"); } - if (entry.Crc < 0) { + if (entry.Crc < 0) + { throw new ZipException("Attempt to write central directory entry with unknown crc"); } @@ -1889,27 +2123,35 @@ int WriteCentralDirectoryHeader(ZipEntry entry) WriteLEShort(entry.Flags); - unchecked { + unchecked + { WriteLEShort((byte)entry.CompressionMethod); WriteLEInt((int)entry.DosTime); WriteLEInt((int)entry.Crc); } - if ((entry.IsZip64Forced()) || (entry.CompressedSize >= 0xffffffff)) { + if ((entry.IsZip64Forced()) || (entry.CompressedSize >= 0xffffffff)) + { WriteLEInt(-1); - } else { + } + else + { WriteLEInt((int)(entry.CompressedSize & 0xffffffff)); } - if ((entry.IsZip64Forced()) || (entry.Size >= 0xffffffff)) { + if ((entry.IsZip64Forced()) || (entry.Size >= 0xffffffff)) + { WriteLEInt(-1); - } else { + } + else + { WriteLEInt((int)entry.Size); } - byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); + byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name); - if (name.Length > 0xFFFF) { + if (name.Length > 0xFFFF) + { throw new ZipException("Entry name is too long."); } @@ -1918,24 +2160,30 @@ int WriteCentralDirectoryHeader(ZipEntry entry) // Central header extra data is different to local header version so regenerate. var ed = new ZipExtraData(entry.ExtraData); - if (entry.CentralHeaderRequiresZip64) { + if (entry.CentralHeaderRequiresZip64) + { ed.StartNewEntry(); - if ((entry.Size >= 0xffffffff) || (useZip64_ == UseZip64.On)) { + if ((entry.Size >= 0xffffffff) || (useZip64_ == UseZip64.On)) + { ed.AddLeLong(entry.Size); } - if ((entry.CompressedSize >= 0xffffffff) || (useZip64_ == UseZip64.On)) { + if ((entry.CompressedSize >= 0xffffffff) || (useZip64_ == UseZip64.On)) + { ed.AddLeLong(entry.CompressedSize); } - if (entry.Offset >= 0xffffffff) { + if (entry.Offset >= 0xffffffff) + { ed.AddLeLong(entry.Offset); } // Number of disk on which this file starts isnt supported and is never written here. ed.AddNewEntry(1); - } else { + } + else + { // Should have already be done when local header was added. ed.Delete(1); } @@ -1949,53 +2197,67 @@ int WriteCentralDirectoryHeader(ZipEntry entry) WriteLEShort(0); // internal file attributes // External file attributes... - if (entry.ExternalFileAttributes != -1) { + if (entry.ExternalFileAttributes != -1) + { WriteLEInt(entry.ExternalFileAttributes); - } else { - if (entry.IsDirectory) { + } + else + { + if (entry.IsDirectory) + { WriteLEUint(16); - } else { + } + else + { WriteLEUint(0); } } - if (entry.Offset >= 0xffffffff) { + if (entry.Offset >= 0xffffffff) + { WriteLEUint(0xffffffff); - } else { + } + else + { WriteLEUint((uint)(int)entry.Offset); } - if (name.Length > 0) { + if (name.Length > 0) + { baseStream_.Write(name, 0, name.Length); } - if (centralExtraData.Length > 0) { + if (centralExtraData.Length > 0) + { baseStream_.Write(centralExtraData, 0, centralExtraData.Length); } byte[] rawComment = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0]; - if (rawComment.Length > 0) { + if (rawComment.Length > 0) + { baseStream_.Write(rawComment, 0, rawComment.Length); } return ZipConstants.CentralHeaderBaseSize + name.Length + centralExtraData.Length + rawComment.Length; } - #endregion - void PostUpdateCleanup() + #endregion Writing Values/Headers + + private void PostUpdateCleanup() { updateDataSource_ = null; updates_ = null; updateIndex_ = null; - if (archiveStorage_ != null) { + if (archiveStorage_ != null) + { archiveStorage_.Dispose(); archiveStorage_ = null; } } - string GetTransformedFileName(string name) + private string GetTransformedFileName(string name) { INameTransform transform = NameTransform; return (transform != null) ? @@ -2003,7 +2265,7 @@ string GetTransformedFileName(string name) name; } - string GetTransformedDirectoryName(string name) + private string GetTransformedDirectoryName(string name) { INameTransform transform = NameTransform; return (transform != null) ? @@ -2015,39 +2277,46 @@ string GetTransformedDirectoryName(string name) /// Get a raw memory buffer. /// /// Returns a raw memory buffer. - byte[] GetBuffer() + private byte[] GetBuffer() { - if (copyBuffer_ == null) { + if (copyBuffer_ == null) + { copyBuffer_ = new byte[bufferSize_]; } return copyBuffer_; } - void CopyDescriptorBytes(ZipUpdate update, Stream dest, Stream source) + private void CopyDescriptorBytes(ZipUpdate update, Stream dest, Stream source) { int bytesToCopy = GetDescriptorSize(update); - if (bytesToCopy > 0) { + if (bytesToCopy > 0) + { byte[] buffer = GetBuffer(); - while (bytesToCopy > 0) { + while (bytesToCopy > 0) + { int readSize = Math.Min(buffer.Length, bytesToCopy); int bytesRead = source.Read(buffer, 0, readSize); - if (bytesRead > 0) { + if (bytesRead > 0) + { dest.Write(buffer, 0, bytesRead); bytesToCopy -= bytesRead; - } else { + } + else + { throw new ZipException("Unxpected end of stream"); } } } } - void CopyBytes(ZipUpdate update, Stream destination, Stream source, + private void CopyBytes(ZipUpdate update, Stream destination, Stream source, long bytesToCopy, bool updateCrc) { - if (destination == source) { + if (destination == source) + { throw new InvalidOperationException("Destination and source are the same"); } @@ -2059,16 +2328,20 @@ void CopyBytes(ZipUpdate update, Stream destination, Stream source, long totalBytesRead = 0; int bytesRead; - do { + do + { int readSize = buffer.Length; - if (bytesToCopy < readSize) { + if (bytesToCopy < readSize) + { readSize = (int)bytesToCopy; } bytesRead = source.Read(buffer, 0, readSize); - if (bytesRead > 0) { - if (updateCrc) { + if (bytesRead > 0) + { + if (updateCrc) + { crc.Update(new ArraySegment(buffer, 0, bytesRead)); } destination.Write(buffer, 0, bytesRead); @@ -2078,11 +2351,13 @@ void CopyBytes(ZipUpdate update, Stream destination, Stream source, } while ((bytesRead > 0) && (bytesToCopy > 0)); - if (totalBytesRead != targetBytes) { + if (totalBytesRead != targetBytes) + { throw new ZipException(string.Format("Failed to copy bytes expected {0} read {1}", targetBytes, totalBytesRead)); } - if (updateCrc) { + if (updateCrc) + { update.OutEntry.Crc = crc.Value; } } @@ -2092,41 +2367,47 @@ void CopyBytes(ZipUpdate update, Stream destination, Stream source, /// /// The update to get the size for. /// The descriptor size, zero if there isnt one. - int GetDescriptorSize(ZipUpdate update) + private int GetDescriptorSize(ZipUpdate update) { int result = 0; - if ((update.Entry.Flags & (int)GeneralBitFlags.Descriptor) != 0) { + if ((update.Entry.Flags & (int)GeneralBitFlags.Descriptor) != 0) + { result = ZipConstants.DataDescriptorSize - 4; - if (update.Entry.LocalHeaderRequiresZip64) { + if (update.Entry.LocalHeaderRequiresZip64) + { result = ZipConstants.Zip64DataDescriptorSize - 4; } } return result; } - void CopyDescriptorBytesDirect(ZipUpdate update, Stream stream, ref long destinationPosition, long sourcePosition) + private void CopyDescriptorBytesDirect(ZipUpdate update, Stream stream, ref long destinationPosition, long sourcePosition) { int bytesToCopy = GetDescriptorSize(update); - while (bytesToCopy > 0) { + while (bytesToCopy > 0) + { var readSize = (int)bytesToCopy; byte[] buffer = GetBuffer(); stream.Position = sourcePosition; int bytesRead = stream.Read(buffer, 0, readSize); - if (bytesRead > 0) { + if (bytesRead > 0) + { stream.Position = destinationPosition; stream.Write(buffer, 0, bytesRead); bytesToCopy -= bytesRead; destinationPosition += bytesRead; sourcePosition += bytesRead; - } else { + } + else + { throw new ZipException("Unxpected end of stream"); } } } - void CopyEntryDataDirect(ZipUpdate update, Stream stream, bool updateCrc, ref long destinationPosition, ref long sourcePosition) + private void CopyEntryDataDirect(ZipUpdate update, Stream stream, bool updateCrc, ref long destinationPosition, ref long sourcePosition) { long bytesToCopy = update.Entry.CompressedSize; @@ -2138,17 +2419,21 @@ void CopyEntryDataDirect(ZipUpdate update, Stream stream, bool updateCrc, ref lo long totalBytesRead = 0; int bytesRead; - do { + do + { int readSize = buffer.Length; - if (bytesToCopy < readSize) { + if (bytesToCopy < readSize) + { readSize = (int)bytesToCopy; } stream.Position = sourcePosition; bytesRead = stream.Read(buffer, 0, readSize); - if (bytesRead > 0) { - if (updateCrc) { + if (bytesRead > 0) + { + if (updateCrc) + { crc.Update(new ArraySegment(buffer, 0, bytesRead)); } stream.Position = destinationPosition; @@ -2162,21 +2447,24 @@ void CopyEntryDataDirect(ZipUpdate update, Stream stream, bool updateCrc, ref lo } while ((bytesRead > 0) && (bytesToCopy > 0)); - if (totalBytesRead != targetBytes) { + if (totalBytesRead != targetBytes) + { throw new ZipException(string.Format("Failed to copy bytes expected {0} read {1}", targetBytes, totalBytesRead)); } - if (updateCrc) { + if (updateCrc) + { update.OutEntry.Crc = crc.Value; } } - int FindExistingUpdate(ZipEntry entry) + private int FindExistingUpdate(ZipEntry entry) { int result = -1; string convertedName = GetTransformedFileName(entry.Name); - if (updateIndex_.ContainsKey(convertedName)) { + if (updateIndex_.ContainsKey(convertedName)) + { result = (int)updateIndex_[convertedName]; } /* @@ -2195,13 +2483,14 @@ int FindExistingUpdate(ZipEntry entry) return result; } - int FindExistingUpdate(string fileName) + private int FindExistingUpdate(string fileName) { int result = -1; string convertedName = GetTransformedFileName(fileName); - if (updateIndex_.ContainsKey(convertedName)) { + if (updateIndex_.ContainsKey(convertedName)) + { result = (int)updateIndex_[convertedName]; } @@ -2225,22 +2514,26 @@ int FindExistingUpdate(string fileName) /// /// The entry to get an output stream for. /// The output stream obtained for the entry. - Stream GetOutputStream(ZipEntry entry) + private Stream GetOutputStream(ZipEntry entry) { Stream result = baseStream_; - if (entry.IsCrypted == true) { + if (entry.IsCrypted == true) + { result = CreateAndInitEncryptionStream(result, entry); } - switch (entry.CompressionMethod) { + switch (entry.CompressionMethod) + { case CompressionMethod.Stored: result = new UncompressedStream(result); break; case CompressionMethod.Deflated: - var dos = new DeflaterOutputStream(result, new Deflater(9, true)); - dos.IsStreamOwner = false; + var dos = new DeflaterOutputStream(result, new Deflater(9, true)) + { + IsStreamOwner = false + }; result = dos; break; @@ -2250,26 +2543,34 @@ Stream GetOutputStream(ZipEntry entry) return result; } - void AddEntry(ZipFile workFile, ZipUpdate update) + private void AddEntry(ZipFile workFile, ZipUpdate update) { Stream source = null; - if (update.Entry.IsFile) { + if (update.Entry.IsFile) + { source = update.GetSource(); - if (source == null) { + if (source == null) + { source = updateDataSource_.GetSource(update.Entry, update.Filename); } } - if (source != null) { - using (source) { + if (source != null) + { + using (source) + { long sourceStreamLength = source.Length; - if (update.OutEntry.Size < 0) { + if (update.OutEntry.Size < 0) + { update.OutEntry.Size = sourceStreamLength; - } else { + } + else + { // Check for errant entries. - if (update.OutEntry.Size != sourceStreamLength) { + if (update.OutEntry.Size != sourceStreamLength) + { throw new ZipException("Entry size/stream size mismatch"); } } @@ -2278,34 +2579,40 @@ void AddEntry(ZipFile workFile, ZipUpdate update) long dataStart = workFile.baseStream_.Position; - using (Stream output = workFile.GetOutputStream(update.OutEntry)) { + using (Stream output = workFile.GetOutputStream(update.OutEntry)) + { CopyBytes(update, output, source, sourceStreamLength, true); } long dataEnd = workFile.baseStream_.Position; update.OutEntry.CompressedSize = dataEnd - dataStart; - if ((update.OutEntry.Flags & (int)GeneralBitFlags.Descriptor) == (int)GeneralBitFlags.Descriptor) { + if ((update.OutEntry.Flags & (int)GeneralBitFlags.Descriptor) == (int)GeneralBitFlags.Descriptor) + { var helper = new ZipHelperStream(workFile.baseStream_); helper.WriteDataDescriptor(update.OutEntry); } } - } else { + } + else + { workFile.WriteLocalEntryHeader(update); update.OutEntry.CompressedSize = 0; } - } - void ModifyEntry(ZipFile workFile, ZipUpdate update) + private void ModifyEntry(ZipFile workFile, ZipUpdate update) { workFile.WriteLocalEntryHeader(update); long dataStart = workFile.baseStream_.Position; // TODO: This is slow if the changes don't effect the data!! - if (update.Entry.IsFile && (update.Filename != null)) { - using (Stream output = workFile.GetOutputStream(update.OutEntry)) { - using (Stream source = this.GetInputStream(update.Entry)) { + if (update.Entry.IsFile && (update.Filename != null)) + { + using (Stream output = workFile.GetOutputStream(update.OutEntry)) + { + using (Stream source = this.GetInputStream(update.Entry)) + { CopyBytes(update, output, source, source.Length, true); } } @@ -2315,11 +2622,12 @@ void ModifyEntry(ZipFile workFile, ZipUpdate update) update.Entry.CompressedSize = dataEnd - dataStart; } - void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPosition) + private void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPosition) { bool skipOver = false || update.Entry.Offset == destinationPosition; - if (!skipOver) { + if (!skipOver) + { baseStream_.Position = destinationPosition; workFile.WriteLocalEntryHeader(update); destinationPosition = baseStream_.Position; @@ -2341,7 +2649,8 @@ void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPos sourcePosition = baseStream_.Position + nameLength + extraLength; - if (skipOver) { + if (skipOver) + { if (update.OffsetBasedSize != -1) destinationPosition += update.OffsetBasedSize; else @@ -2351,19 +2660,23 @@ void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPos destinationPosition += (sourcePosition - entryDataOffset) + NameLengthOffset + // Header size update.Entry.CompressedSize + GetDescriptorSize(update); - } else { - if (update.Entry.CompressedSize > 0) { + } + else + { + if (update.Entry.CompressedSize > 0) + { CopyEntryDataDirect(update, baseStream_, false, ref destinationPosition, ref sourcePosition); } CopyDescriptorBytesDirect(update, baseStream_, ref destinationPosition, sourcePosition); } } - void CopyEntry(ZipFile workFile, ZipUpdate update) + private void CopyEntry(ZipFile workFile, ZipUpdate update) { workFile.WriteLocalEntryHeader(update); - if (update.Entry.CompressedSize > 0) { + if (update.Entry.CompressedSize > 0) + { const int NameLengthOffset = 26; long entryDataOffset = update.Entry.Offset + NameLengthOffset; @@ -2381,43 +2694,46 @@ void CopyEntry(ZipFile workFile, ZipUpdate update) CopyDescriptorBytes(update, workFile.baseStream_, baseStream_); } - void Reopen(Stream source) + private void Reopen(Stream source) { - if (source == null) { - throw new ZipException("Failed to reopen archive - no source"); - } - isNewArchive_ = false; - baseStream_ = source; + baseStream_ = source ?? throw new ZipException("Failed to reopen archive - no source"); ReadEntries(); } - void Reopen() + private void Reopen() { - if (Name == null) { + if (Name == null) + { throw new InvalidOperationException("Name is not known cannot Reopen"); } Reopen(File.Open(Name, FileMode.Open, FileAccess.Read, FileShare.Read)); } - void UpdateCommentOnly() + private void UpdateCommentOnly() { long baseLength = baseStream_.Length; ZipHelperStream updateFile = null; - if (archiveStorage_.UpdateMode == FileUpdateMode.Safe) { + if (archiveStorage_.UpdateMode == FileUpdateMode.Safe) + { Stream copyStream = archiveStorage_.MakeTemporaryCopy(baseStream_); - updateFile = new ZipHelperStream(copyStream); - updateFile.IsStreamOwner = true; + updateFile = new ZipHelperStream(copyStream) + { + IsStreamOwner = true + }; baseStream_.Dispose(); baseStream_ = null; - } else { - if (archiveStorage_.UpdateMode == FileUpdateMode.Direct) { + } + else + { + if (archiveStorage_.UpdateMode == FileUpdateMode.Direct) + { // TODO: archiveStorage wasnt originally intended for this use. - // Need to revisit this to tidy up handling as archive storage currently doesnt + // Need to revisit this to tidy up handling as archive storage currently doesnt // handle the original stream well. // The problem is when using an existing zip archive with an in memory archive storage. // The open stream wont support writing but the memory storage should open the same file not an in memory one. @@ -2425,18 +2741,22 @@ void UpdateCommentOnly() // Need to tidy up the archive storage interface and contract basically. baseStream_ = archiveStorage_.OpenForDirectUpdate(baseStream_); updateFile = new ZipHelperStream(baseStream_); - } else { + } + else + { baseStream_.Dispose(); baseStream_ = null; updateFile = new ZipHelperStream(Name); } } - using (updateFile) { + using (updateFile) + { long locatedCentralDirOffset = updateFile.LocateBlockWithSignature(ZipConstants.EndOfCentralDirectorySignature, baseLength, ZipConstants.EndOfCentralRecordBaseSize, 0xffff); - if (locatedCentralDirOffset < 0) { + if (locatedCentralDirOffset < 0) + { throw new ZipException("Cannot find central directory"); } @@ -2450,9 +2770,12 @@ void UpdateCommentOnly() updateFile.SetLength(updateFile.Position); } - if (archiveStorage_.UpdateMode == FileUpdateMode.Safe) { + if (archiveStorage_.UpdateMode == FileUpdateMode.Safe) + { Reopen(archiveStorage_.ConvertTemporaryToFinal()); - } else { + } + else + { ReadEntries(); } } @@ -2460,10 +2783,10 @@ void UpdateCommentOnly() /// /// Class used to sort updates. /// - class UpdateComparer : IComparer + private class UpdateComparer : IComparer { /// - /// Compares two objects and returns a value indicating whether one is + /// Compares two objects and returns a value indicating whether one is /// less than, equal to or greater than the other. /// /// First object to compare @@ -2473,26 +2796,40 @@ public int Compare(ZipUpdate x, ZipUpdate y) { int result; - if (x == null) { - if (y == null) { + if (x == null) + { + if (y == null) + { result = 0; - } else { + } + else + { result = -1; } - } else if (y == null) { + } + else if (y == null) + { result = 1; - } else { + } + else + { int xCmdValue = ((x.Command == UpdateCommand.Copy) || (x.Command == UpdateCommand.Modify)) ? 0 : 1; int yCmdValue = ((y.Command == UpdateCommand.Copy) || (y.Command == UpdateCommand.Modify)) ? 0 : 1; result = xCmdValue - yCmdValue; - if (result == 0) { + if (result == 0) + { long offsetDiff = x.Entry.Offset - y.Entry.Offset; - if (offsetDiff < 0) { + if (offsetDiff < 0) + { result = -1; - } else if (offsetDiff == 0) { + } + else if (offsetDiff == 0) + { result = 0; - } else { + } + else + { result = 1; } } @@ -2501,7 +2838,7 @@ public int Compare(ZipUpdate x, ZipUpdate y) } } - void RunUpdates() + private void RunUpdates() { long sizeEntries = 0; long endOfStream = 0; @@ -2510,11 +2847,14 @@ void RunUpdates() ZipFile workFile; - if (IsNewArchive) { + if (IsNewArchive) + { workFile = this; workFile.baseStream_.Position = 0; directUpdate = true; - } else if (archiveStorage_.UpdateMode == FileUpdateMode.Direct) { + } + else if (archiveStorage_.UpdateMode == FileUpdateMode.Direct) + { workFile = this; workFile.baseStream_.Position = 0; directUpdate = true; @@ -2522,23 +2862,33 @@ void RunUpdates() // Sort the updates by offset within copies/modifies, then adds. // This ensures that data required by copies will not be overwritten. updates_.Sort(new UpdateComparer()); - } else { + } + else + { workFile = ZipFile.Create(archiveStorage_.GetTemporaryOutput()); workFile.UseZip64 = UseZip64; - if (key != null) { + if (key != null) + { workFile.key = (byte[])key.Clone(); } } - try { - foreach (ZipUpdate update in updates_) { - if (update != null) { - switch (update.Command) { + try + { + foreach (ZipUpdate update in updates_) + { + if (update != null) + { + switch (update.Command) + { case UpdateCommand.Copy: - if (directUpdate) { + if (directUpdate) + { CopyEntryDirect(workFile, update, ref destinationPosition); - } else { + } + else + { CopyEntry(workFile, update); } break; @@ -2549,13 +2899,15 @@ void RunUpdates() break; case UpdateCommand.Add: - if (!IsNewArchive && directUpdate) { + if (!IsNewArchive && directUpdate) + { workFile.baseStream_.Position = destinationPosition; } AddEntry(workFile, update); - if (directUpdate) { + if (directUpdate) + { destinationPosition = workFile.baseStream_.Position; } break; @@ -2563,82 +2915,102 @@ void RunUpdates() } } - if (!IsNewArchive && directUpdate) { + if (!IsNewArchive && directUpdate) + { workFile.baseStream_.Position = destinationPosition; } long centralDirOffset = workFile.baseStream_.Position; - foreach (ZipUpdate update in updates_) { - if (update != null) { + foreach (ZipUpdate update in updates_) + { + if (update != null) + { sizeEntries += workFile.WriteCentralDirectoryHeader(update.OutEntry); } } - byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipConstants.ConvertToArray(comment_); - using (ZipHelperStream zhs = new ZipHelperStream(workFile.baseStream_)) { + byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipStrings.ConvertToArray(comment_); + using (ZipHelperStream zhs = new ZipHelperStream(workFile.baseStream_)) + { zhs.WriteEndOfCentralDirectory(updateCount_, sizeEntries, centralDirOffset, theComment); } endOfStream = workFile.baseStream_.Position; // And now patch entries... - foreach (ZipUpdate update in updates_) { - if (update != null) { + foreach (ZipUpdate update in updates_) + { + if (update != null) + { // If the size of the entry is zero leave the crc as 0 as well. // The calculated crc will be all bits on... - if ((update.CrcPatchOffset > 0) && (update.OutEntry.CompressedSize > 0)) { + if ((update.CrcPatchOffset > 0) && (update.OutEntry.CompressedSize > 0)) + { workFile.baseStream_.Position = update.CrcPatchOffset; workFile.WriteLEInt((int)update.OutEntry.Crc); } - if (update.SizePatchOffset > 0) { + if (update.SizePatchOffset > 0) + { workFile.baseStream_.Position = update.SizePatchOffset; - if (update.OutEntry.LocalHeaderRequiresZip64) { + if (update.OutEntry.LocalHeaderRequiresZip64) + { workFile.WriteLeLong(update.OutEntry.Size); workFile.WriteLeLong(update.OutEntry.CompressedSize); - } else { + } + else + { workFile.WriteLEInt((int)update.OutEntry.CompressedSize); workFile.WriteLEInt((int)update.OutEntry.Size); } } } } - } catch { + } + catch + { workFile.Close(); - if (!directUpdate && (workFile.Name != null)) { + if (!directUpdate && (workFile.Name != null)) + { File.Delete(workFile.Name); } throw; } - if (directUpdate) { + if (directUpdate) + { workFile.baseStream_.SetLength(endOfStream); workFile.baseStream_.Flush(); isNewArchive_ = false; ReadEntries(); - } else { + } + else + { baseStream_.Dispose(); Reopen(archiveStorage_.ConvertTemporaryToFinal()); } } - void CheckUpdating() + private void CheckUpdating() { - if (updates_ == null) { + if (updates_ == null) + { throw new InvalidOperationException("BeginUpdate has not been called"); } } - #endregion + #endregion Update Support #region ZipUpdate class + /// /// Represents a pending update to a Zip file. /// - class ZipUpdate + private class ZipUpdate { #region Constructors + public ZipUpdate(string fileName, ZipEntry entry) { command_ = UpdateCommand.Add; @@ -2650,8 +3022,10 @@ public ZipUpdate(string fileName, ZipEntry entry) public ZipUpdate(string fileName, string entryName, CompressionMethod compressionMethod) { command_ = UpdateCommand.Add; - entry_ = new ZipEntry(entryName); - entry_.CompressionMethod = compressionMethod; + entry_ = new ZipEntry(entryName) + { + CompressionMethod = compressionMethod + }; filename_ = fileName; } @@ -2666,8 +3040,10 @@ public ZipUpdate(string fileName, string entryName) public ZipUpdate(IStaticDataSource dataSource, string entryName, CompressionMethod compressionMethod) { command_ = UpdateCommand.Add; - entry_ = new ZipEntry(entryName); - entry_.CompressionMethod = compressionMethod; + entry_ = new ZipEntry(entryName) + { + CompressionMethod = compressionMethod + }; dataSource_ = dataSource; } @@ -2694,7 +3070,6 @@ public ZipUpdate(UpdateCommand command, ZipEntry entry) entry_ = (ZipEntry)entry.Clone(); } - /// /// Copy an existing entry. /// @@ -2704,22 +3079,27 @@ public ZipUpdate(ZipEntry entry) { // Do nothing. } - #endregion + + #endregion Constructors /// /// Get the for this update. /// /// This is the source or original entry. - public ZipEntry Entry { + public ZipEntry Entry + { get { return entry_; } } /// /// Get the that will be written to the updated/new file. /// - public ZipEntry OutEntry { - get { - if (outEntry_ == null) { + public ZipEntry OutEntry + { + get + { + if (outEntry_ == null) + { outEntry_ = (ZipEntry)entry_.Clone(); } @@ -2730,21 +3110,24 @@ public ZipEntry OutEntry { /// /// Get the command for this update. /// - public UpdateCommand Command { + public UpdateCommand Command + { get { return command_; } } /// /// Get the filename if any for this update. Null if none exists. /// - public string Filename { + public string Filename + { get { return filename_; } } /// /// Get/set the location of the size patch for this update. /// - public long SizePatchOffset { + public long SizePatchOffset + { get { return sizePatchOffset_; } set { sizePatchOffset_ = value; } } @@ -2752,7 +3135,8 @@ public long SizePatchOffset { /// /// Get /set the location of the crc patch for this update. /// - public long CrcPatchOffset { + public long CrcPatchOffset + { get { return crcPatchOffset_; } set { crcPatchOffset_ = value; } } @@ -2761,7 +3145,8 @@ public long CrcPatchOffset { /// Get/set the size calculated by offset. /// Specifically, the difference between this and next entry's starting offset. /// - public long OffsetBasedSize { + public long OffsetBasedSize + { get { return _offsetBasedSize; } set { _offsetBasedSize = value; } } @@ -2769,7 +3154,8 @@ public long OffsetBasedSize { public Stream GetSource() { Stream result = null; - if (dataSource_ != null) { + if (dataSource_ != null) + { result = dataSource_.GetSource(); } @@ -2777,37 +3163,45 @@ public Stream GetSource() } #region Instance Fields - ZipEntry entry_; - ZipEntry outEntry_; - UpdateCommand command_; - IStaticDataSource dataSource_; - string filename_; - long sizePatchOffset_ = -1; - long crcPatchOffset_ = -1; - long _offsetBasedSize = -1; - #endregion + + private ZipEntry entry_; + private ZipEntry outEntry_; + private readonly UpdateCommand command_; + private IStaticDataSource dataSource_; + private readonly string filename_; + private long sizePatchOffset_ = -1; + private long crcPatchOffset_ = -1; + private long _offsetBasedSize = -1; + + #endregion Instance Fields } - #endregion - #endregion + #endregion ZipUpdate class + + #endregion Updating #region Disposing #region IDisposable Members + void IDisposable.Dispose() { Close(); } - #endregion - void DisposeInternal(bool disposing) + #endregion IDisposable Members + + private void DisposeInternal(bool disposing) { - if (!isDisposed_) { + if (!isDisposed_) + { isDisposed_ = true; entries_ = new ZipEntry[0]; - if (IsStreamOwner && (baseStream_ != null)) { - lock (baseStream_) { + if (IsStreamOwner && (baseStream_ != null)) + { + lock (baseStream_) + { baseStream_.Dispose(); } } @@ -2826,10 +3220,12 @@ protected virtual void Dispose(bool disposing) DisposeInternal(disposing); } - #endregion + #endregion Disposing #region Internal routines + #region Reading + /// /// Read an unsigned short in little endian byte order. /// @@ -2837,21 +3233,22 @@ protected virtual void Dispose(bool disposing) /// /// The stream ends prematurely /// - ushort ReadLEUshort() + private ushort ReadLEUshort() { int data1 = baseStream_.ReadByte(); - if (data1 < 0) { + if (data1 < 0) + { throw new EndOfStreamException("End of stream"); } int data2 = baseStream_.ReadByte(); - if (data2 < 0) { + if (data2 < 0) + { throw new EndOfStreamException("End of stream"); } - return unchecked((ushort)((ushort)data1 | (ushort)(data2 << 8))); } @@ -2865,21 +3262,23 @@ ushort ReadLEUshort() /// /// The file ends prematurely /// - uint ReadLEUint() + private uint ReadLEUint() { return (uint)(ReadLEUshort() | (ReadLEUshort() << 16)); } - ulong ReadLEUlong() + private ulong ReadLEUlong() { return ReadLEUint() | ((ulong)ReadLEUint() << 32); } - #endregion + #endregion Reading + // NOTE this returns the offset of the first byte after the signature. - long LocateBlockWithSignature(int signature, long endLocation, int minimumBlockSize, int maximumVariableData) + private long LocateBlockWithSignature(int signature, long endLocation, int minimumBlockSize, int maximumVariableData) { - using (ZipHelperStream les = new ZipHelperStream(baseStream_)) { + using (ZipHelperStream les = new ZipHelperStream(baseStream_)) + { return les.LocateBlockWithSignature(signature, endLocation, minimumBlockSize, maximumVariableData); } } @@ -2893,25 +3292,27 @@ long LocateBlockWithSignature(int signature, long endLocation, int minimumBlockS /// /// The central directory is malformed or cannot be found /// - void ReadEntries() + private void ReadEntries() { // Search for the End Of Central Directory. When a zip comment is // present the directory will start earlier - // + // // The search is limited to 64K which is the maximum size of a trailing comment field to aid speed. // This should be compatible with both SFX and ZIP files but has only been tested for Zip files // If a SFX file has the Zip data attached as a resource and there are other resources occuring later then // this could be invalid. - // Could also speed this up by reading memory in larger blocks. + // Could also speed this up by reading memory in larger blocks. - if (baseStream_.CanSeek == false) { + if (baseStream_.CanSeek == false) + { throw new ZipException("ZipFile stream must be seekable"); } long locatedEndOfCentralDir = LocateBlockWithSignature(ZipConstants.EndOfCentralDirectorySignature, baseStream_.Length, ZipConstants.EndOfCentralRecordBaseSize, 0xffff); - if (locatedEndOfCentralDir < 0) { + if (locatedEndOfCentralDir < 0) + { throw new ZipException("Cannot find central directory"); } @@ -2924,12 +3325,15 @@ void ReadEntries() long offsetOfCentralDir = ReadLEUint(); uint commentSize = ReadLEUshort(); - if (commentSize > 0) { + if (commentSize > 0) + { byte[] comment = new byte[commentSize]; StreamUtils.ReadFully(baseStream_, comment); - comment_ = ZipConstants.ConvertToString(comment); - } else { + comment_ = ZipStrings.ConvertToString(comment); + } + else + { comment_ = string.Empty; } @@ -2941,17 +3345,19 @@ void ReadEntries() (entriesForThisDisk == 0xffff) || (entriesForWholeCentralDir == 0xffff) || (centralDirSize == 0xffffffff) || - (offsetOfCentralDir == 0xffffffff)) { + (offsetOfCentralDir == 0xffffffff)) + { isZip64 = true; long offset = LocateBlockWithSignature(ZipConstants.Zip64CentralDirLocatorSignature, locatedEndOfCentralDir, 0, 0x1000); - if (offset < 0) { + if (offset < 0) + { throw new ZipException("Cannot find Zip64 locator"); } - // number of the disk with the start of the zip64 end of central directory 4 bytes - // relative offset of the zip64 end of central directory record 8 bytes - // total number of disks 4 bytes + // number of the disk with the start of the zip64 end of central directory 4 bytes + // relative offset of the zip64 end of central directory record 8 bytes + // total number of disks 4 bytes ReadLEUint(); // startDisk64 is not currently used ulong offset64 = ReadLEUlong(); uint totalDisks = ReadLEUint(); @@ -2959,7 +3365,8 @@ void ReadEntries() baseStream_.Position = (long)offset64; long sig64 = ReadLEUint(); - if (sig64 != ZipConstants.Zip64CentralFileHeaderSignature) { + if (sig64 != ZipConstants.Zip64CentralFileHeaderSignature) + { throw new ZipException(string.Format("Invalid Zip64 Central directory signature at {0:X}", offset64)); } @@ -2985,17 +3392,21 @@ void ReadEntries() // Zip files created by some archivers have the offsets altered to reflect the true offsets // and so dont require any adjustment here... // TODO: Difficulty with Zip64 and SFX offset handling needs resolution - maths? - if (!isZip64 && (offsetOfCentralDir < locatedEndOfCentralDir - (4 + (long)centralDirSize))) { + if (!isZip64 && (offsetOfCentralDir < locatedEndOfCentralDir - (4 + (long)centralDirSize))) + { offsetOfFirstEntry = locatedEndOfCentralDir - (4 + (long)centralDirSize + offsetOfCentralDir); - if (offsetOfFirstEntry <= 0) { + if (offsetOfFirstEntry <= 0) + { throw new ZipException("Invalid embedded zip archive"); } } baseStream_.Seek(offsetOfFirstEntry + offsetOfCentralDir, SeekOrigin.Begin); - for (ulong i = 0; i < entriesForThisDisk; i++) { - if (ReadLEUint() != ZipConstants.CentralHeaderSignature) { + for (ulong i = 0; i < entriesForThisDisk; i++) + { + if (ReadLEUint() != ZipConstants.CentralHeaderSignature) + { throw new ZipException("Wrong Central Directory signature"); } @@ -3020,25 +3431,31 @@ void ReadEntries() byte[] buffer = new byte[Math.Max(nameLen, commentLen)]; StreamUtils.ReadFully(baseStream_, buffer, 0, nameLen); - string name = ZipConstants.ConvertToStringExt(bitFlags, buffer, nameLen); - - var entry = new ZipEntry(name, versionToExtract, versionMadeBy, (CompressionMethod)method); - entry.Crc = crc & 0xffffffffL; - entry.Size = size & 0xffffffffL; - entry.CompressedSize = csize & 0xffffffffL; - entry.Flags = bitFlags; - entry.DosTime = (uint)dostime; - entry.ZipFileIndex = (long)i; - entry.Offset = offset; - entry.ExternalFileAttributes = (int)externalAttributes; - - if ((bitFlags & 8) == 0) { + string name = ZipStrings.ConvertToStringExt(bitFlags, buffer, nameLen); + + var entry = new ZipEntry(name, versionToExtract, versionMadeBy, (CompressionMethod)method) + { + Crc = crc & 0xffffffffL, + Size = size & 0xffffffffL, + CompressedSize = csize & 0xffffffffL, + Flags = bitFlags, + DosTime = dostime, + ZipFileIndex = (long)i, + Offset = offset, + ExternalFileAttributes = (int)externalAttributes + }; + + if ((bitFlags & 8) == 0) + { entry.CryptoCheckValue = (byte)(crc >> 24); - } else { + } + else + { entry.CryptoCheckValue = (byte)((dostime >> 8) & 0xff); } - if (extraLen > 0) { + if (extraLen > 0) + { byte[] extra = new byte[extraLen]; StreamUtils.ReadFully(baseStream_, extra); entry.ExtraData = extra; @@ -3046,9 +3463,10 @@ void ReadEntries() entry.ProcessExtraData(false); - if (commentLen > 0) { + if (commentLen > 0) + { StreamUtils.ReadFully(baseStream_, buffer, 0, commentLen); - entry.Comment = ZipConstants.ConvertToStringExt(bitFlags, buffer, commentLen); + entry.Comment = ZipStrings.ConvertToStringExt(bitFlags, buffer, commentLen); } entries_[i] = entry; @@ -3068,31 +3486,37 @@ void ReadEntries() /// The local header signature is invalid, the entry and central header file name lengths are different /// or the local and entry compression methods dont match /// - long LocateEntry(ZipEntry entry) + private long LocateEntry(ZipEntry entry) { return TestLocalHeader(entry, HeaderTest.Extract); } - Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) + private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) { CryptoStream result = null; if ((entry.Version < ZipConstants.VersionStrongEncryption) - || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) { + || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) + { var classicManaged = new PkzipClassicManaged(); OnKeysRequired(entry.Name); - if (HaveKeys == false) { + if (HaveKeys == false) + { throw new ZipException("No password available for encrypted stream"); } result = new CryptoStream(baseStream, classicManaged.CreateDecryptor(key, null), CryptoStreamMode.Read); CheckClassicPassword(result, entry); - } else { - if (entry.Version == ZipConstants.VERSION_AES) { + } + else + { + if (entry.Version == ZipConstants.VERSION_AES) + { // OnKeysRequired(entry.Name); - if (HaveKeys == false) { + if (HaveKeys == false) + { throw new ZipException("No password available for AES encrypted stream"); } int saltLen = entry.AESSaltLen; @@ -3110,7 +3534,9 @@ Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) if (pwdVerifyCalc[0] != pwdVerifyRead[0] || pwdVerifyCalc[1] != pwdVerifyRead[1]) throw new ZipException("Invalid password for AES"); result = new ZipAESStream(baseStream, decryptor, CryptoStreamMode.Read); - } else { + } + else + { throw new ZipException("Decryption method not supported"); } } @@ -3118,15 +3544,17 @@ Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) return result; } - Stream CreateAndInitEncryptionStream(Stream baseStream, ZipEntry entry) + private Stream CreateAndInitEncryptionStream(Stream baseStream, ZipEntry entry) { CryptoStream result = null; if ((entry.Version < ZipConstants.VersionStrongEncryption) - || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) { + || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) + { var classicManaged = new PkzipClassicManaged(); OnKeysRequired(entry.Name); - if (HaveKeys == false) { + if (HaveKeys == false) + { throw new ZipException("No password available for encrypted stream"); } @@ -3135,25 +3563,29 @@ Stream CreateAndInitEncryptionStream(Stream baseStream, ZipEntry entry) result = new CryptoStream(new UncompressedStream(baseStream), classicManaged.CreateEncryptor(key, null), CryptoStreamMode.Write); - if ((entry.Crc < 0) || (entry.Flags & 8) != 0) { + if ((entry.Crc < 0) || (entry.Flags & 8) != 0) + { WriteEncryptionHeader(result, entry.DosTime << 16); - } else { + } + else + { WriteEncryptionHeader(result, entry.Crc); } } return result; } - static void CheckClassicPassword(CryptoStream classicCryptoStream, ZipEntry entry) + private static void CheckClassicPassword(CryptoStream classicCryptoStream, ZipEntry entry) { byte[] cryptbuffer = new byte[ZipConstants.CryptoHeaderSize]; StreamUtils.ReadFully(classicCryptoStream, cryptbuffer); - if (cryptbuffer[ZipConstants.CryptoHeaderSize - 1] != entry.CryptoCheckValue) { + if (cryptbuffer[ZipConstants.CryptoHeaderSize - 1] != entry.CryptoCheckValue) + { throw new ZipException("Invalid password"); } } - static void WriteEncryptionHeader(Stream stream, long crcValue) + private static void WriteEncryptionHeader(Stream stream, long crcValue) { byte[] cryptBuffer = new byte[ZipConstants.CryptoHeaderSize]; var rnd = new Random(); @@ -3162,48 +3594,54 @@ static void WriteEncryptionHeader(Stream stream, long crcValue) stream.Write(cryptBuffer, 0, cryptBuffer.Length); } - #endregion + #endregion Internal routines #region Instance Fields - bool isDisposed_; - string name_; - string comment_; - string rawPassword_; - Stream baseStream_; - bool isStreamOwner; - long offsetOfFirstEntry; - ZipEntry[] entries_; - byte[] key; - bool isNewArchive_; + + private bool isDisposed_; + private string name_; + private string comment_; + private string rawPassword_; + private Stream baseStream_; + private bool isStreamOwner; + private long offsetOfFirstEntry; + private ZipEntry[] entries_; + private byte[] key; + private bool isNewArchive_; // Default is dynamic which is not backwards compatible and can cause problems // with XP's built in compression which cant read Zip64 archives. // However it does avoid the situation were a large file is added and cannot be completed correctly. // Hint: Set always ZipEntry size before they are added to an archive and this setting isnt needed. - UseZip64 useZip64_ = UseZip64.Dynamic; + private UseZip64 useZip64_ = UseZip64.Dynamic; #region Zip Update Instance Fields - List updates_; - long updateCount_; // Count is managed manually as updates_ can contain nulls! - Dictionary updateIndex_; - IArchiveStorage archiveStorage_; - IDynamicDataSource updateDataSource_; - bool contentsEdited_; - int bufferSize_ = DefaultBufferSize; - byte[] copyBuffer_; - ZipString newComment_; - bool commentEdited_; - IEntryFactory updateEntryFactory_ = new ZipEntryFactory(); - #endregion - #endregion + + private List updates_; + private long updateCount_; // Count is managed manually as updates_ can contain nulls! + private Dictionary updateIndex_; + private IArchiveStorage archiveStorage_; + private IDynamicDataSource updateDataSource_; + private bool contentsEdited_; + private int bufferSize_ = DefaultBufferSize; + private byte[] copyBuffer_; + private ZipString newComment_; + private bool commentEdited_; + private IEntryFactory updateEntryFactory_ = new ZipEntryFactory(); + + #endregion Zip Update Instance Fields + + #endregion Instance Fields #region Support Classes + /// /// Represents a string from a which is stored as an array of bytes. /// - class ZipString + private class ZipString { #region Constructors + /// /// Initialise a with a string. /// @@ -3222,21 +3660,25 @@ public ZipString(byte[] rawString) { rawComment_ = rawString; } - #endregion + + #endregion Constructors /// /// Get a value indicating the original source of data for this instance. /// True if the source was a string; false if the source was binary data. /// - public bool IsSourceString { + public bool IsSourceString + { get { return isSourceString_; } } /// /// Get the length of the comment when represented as raw bytes. /// - public int RawLength { - get { + public int RawLength + { + get + { MakeBytesAvailable(); return rawComment_.Length; } @@ -3245,8 +3687,10 @@ public int RawLength { /// /// Get the comment in its 'raw' form as plain bytes. /// - public byte[] RawComment { - get { + public byte[] RawComment + { + get + { MakeBytesAvailable(); return (byte[])rawComment_.Clone(); } @@ -3257,24 +3701,29 @@ public byte[] RawComment { /// public void Reset() { - if (isSourceString_) { + if (isSourceString_) + { rawComment_ = null; - } else { + } + else + { comment_ = null; } } - void MakeTextAvailable() + private void MakeTextAvailable() { - if (comment_ == null) { - comment_ = ZipConstants.ConvertToString(rawComment_); + if (comment_ == null) + { + comment_ = ZipStrings.ConvertToString(rawComment_); } } - void MakeBytesAvailable() + private void MakeBytesAvailable() { - if (rawComment_ == null) { - rawComment_ = ZipConstants.ConvertToArray(comment_); + if (rawComment_ == null) + { + rawComment_ = ZipStrings.ConvertToArray(comment_); } } @@ -3290,27 +3739,34 @@ static public implicit operator string(ZipString zipString) } #region Instance Fields - string comment_; - byte[] rawComment_; - bool isSourceString_; - #endregion + + private string comment_; + private byte[] rawComment_; + private readonly bool isSourceString_; + + #endregion Instance Fields } /// /// An enumerator for Zip entries /// - class ZipEntryEnumerator : IEnumerator + private class ZipEntryEnumerator : IEnumerator { #region Constructors + public ZipEntryEnumerator(ZipEntry[] entries) { array = entries; } - #endregion + #endregion Constructors + #region IEnumerator Members - public object Current { - get { + + public object Current + { + get + { return array[index]; } } @@ -3324,33 +3780,39 @@ public bool MoveNext() { return (++index < array.Length); } - #endregion + + #endregion IEnumerator Members + #region Instance Fields - ZipEntry[] array; - int index = -1; - #endregion + + private ZipEntry[] array; + private int index = -1; + + #endregion Instance Fields } /// /// An is a stream that you can write uncompressed data /// to and flush, but cannot read, seek or do anything else to. /// - class UncompressedStream : Stream + private class UncompressedStream : Stream { #region Constructors + public UncompressedStream(Stream baseStream) { baseStream_ = baseStream; } - #endregion - + #endregion Constructors /// /// Gets a value indicating whether the current stream supports reading. /// - public override bool CanRead { - get { + public override bool CanRead + { + get + { return false; } } @@ -3366,8 +3828,10 @@ public override void Flush() /// /// Gets a value indicating whether the current stream supports writing. /// - public override bool CanWrite { - get { + public override bool CanWrite + { + get + { return baseStream_.CanWrite; } } @@ -3375,8 +3839,10 @@ public override bool CanWrite { /// /// Gets a value indicating whether the current stream supports seeking. /// - public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return false; } } @@ -3384,8 +3850,10 @@ public override bool CanSeek { /// /// Get the length in bytes of the stream. /// - public override long Length { - get { + public override long Length + { + get + { return 0; } } @@ -3393,11 +3861,14 @@ public override long Length { /// /// Gets or sets the position within the current stream. /// - public override long Position { - get { + public override long Position + { + get + { return baseStream_.Position; } - set { + set + { throw new NotImplementedException(); } } @@ -3466,20 +3937,23 @@ public override void Write(byte[] buffer, int offset, int count) baseStream_.Write(buffer, offset, count); } - readonly + private readonly #region Instance Fields + Stream baseStream_; - #endregion + + #endregion Instance Fields } /// /// A is an /// whose data is only a part or subsection of a file. /// - class PartialInputStream : Stream + private class PartialInputStream : Stream { #region Constructors + /// /// Initialise a new instance of the class. /// @@ -3506,7 +3980,8 @@ public PartialInputStream(ZipFile zipFile, long start, long length) readPos_ = start; end_ = start + length; } - #endregion + + #endregion Constructors /// /// Read a byte from this stream. @@ -3514,12 +3989,14 @@ public PartialInputStream(ZipFile zipFile, long start, long length) /// Returns the byte read or -1 on end of stream. public override int ReadByte() { - if (readPos_ >= end_) { + if (readPos_ >= end_) + { // -1 is the correct value at end of stream. return -1; } - lock (baseStream_) { + lock (baseStream_) + { baseStream_.Seek(readPos_++, SeekOrigin.Begin); return baseStream_.ReadByte(); } @@ -3542,20 +4019,25 @@ public override int ReadByte() /// offset or count is negative. public override int Read(byte[] buffer, int offset, int count) { - lock (baseStream_) { - if (count > end_ - readPos_) { + lock (baseStream_) + { + if (count > end_ - readPos_) + { count = (int)(end_ - readPos_); - if (count == 0) { + if (count == 0) + { return 0; } } // Protect against Stream implementations that throw away their buffer on every Seek // (for example, Mono FileStream) - if (baseStream_.Position != readPos_) { + if (baseStream_.Position != readPos_) + { baseStream_.Seek(readPos_, SeekOrigin.Begin); } int readCount = baseStream_.Read(buffer, offset, count); - if (readCount > 0) { + if (readCount > 0) + { readPos_ += readCount; } return readCount; @@ -3606,7 +4088,8 @@ public override long Seek(long offset, SeekOrigin origin) { long newPos = readPos_; - switch (origin) { + switch (origin) + { case SeekOrigin.Begin: newPos = start_ + offset; break; @@ -3620,11 +4103,13 @@ public override long Seek(long offset, SeekOrigin origin) break; } - if (newPos < start_) { + if (newPos < start_) + { throw new ArgumentException("Negative position is invalid"); } - if (newPos >= end_) { + if (newPos >= end_) + { throw new IOException("Cannot seek past end"); } readPos_ = newPos; @@ -3648,16 +4133,20 @@ public override void Flush() /// An I/O error occurs. /// The stream does not support seeking. /// Methods were called after the stream was closed. - public override long Position { + public override long Position + { get { return readPos_ - start_; } - set { + set + { long newPos = start_ + value; - if (newPos < start_) { + if (newPos < start_) + { throw new ArgumentException("Negative position is invalid"); } - if (newPos >= end_) { + if (newPos >= end_) + { throw new InvalidOperationException("Cannot seek past end"); } readPos_ = newPos; @@ -3671,7 +4160,8 @@ public override long Position { /// A long value representing the length of the stream in bytes. /// A class derived from Stream does not support seeking. /// Methods were called after the stream was closed. - public override long Length { + public override long Length + { get { return length_; } } @@ -3680,7 +4170,8 @@ public override long Length { /// /// false /// true if the stream supports writing; otherwise, false. - public override bool CanWrite { + public override bool CanWrite + { get { return false; } } @@ -3689,7 +4180,8 @@ public override bool CanWrite { /// /// true /// true if the stream supports seeking; otherwise, false. - public override bool CanSeek { + public override bool CanSeek + { get { return true; } } @@ -3698,7 +4190,8 @@ public override bool CanSeek { /// /// true. /// true if the stream supports reading; otherwise, false. - public override bool CanRead { + public override bool CanRead + { get { return true; } } @@ -3707,24 +4200,30 @@ public override bool CanRead { /// /// /// A value that determines whether the current stream can time out. - public override bool CanTimeout { + public override bool CanTimeout + { get { return baseStream_.CanTimeout; } } + #region Instance Fields - ZipFile zipFile_; - Stream baseStream_; - long start_; - long length_; - long readPos_; - long end_; - #endregion + + private ZipFile zipFile_; + private Stream baseStream_; + private readonly long start_; + private readonly long length_; + private long readPos_; + private readonly long end_; + + #endregion Instance Fields } - #endregion + + #endregion Support Classes } - #endregion + #endregion ZipFile Class #region DataSources + /// /// Provides a static way to obtain a source of data for an entry. /// @@ -3779,22 +4278,24 @@ public Stream GetSource() return File.Open(fileName_, FileMode.Open, FileAccess.Read, FileShare.Read); } - readonly + private readonly + + #endregion IDataSource Members - #endregion #region Instance Fields + string fileName_; - #endregion - } + #endregion Instance Fields + } /// /// Default implementation of for files stored on disk. /// public class DynamicDiskDataSource : IDynamicDataSource { - #region IDataSource Members + /// /// Get a providing data for an entry. /// @@ -3805,19 +4306,21 @@ public Stream GetSource(ZipEntry entry, string name) { Stream result = null; - if (name != null) { + if (name != null) + { result = File.Open(name, FileMode.Open, FileAccess.Read, FileShare.Read); } return result; } - #endregion + #endregion IDataSource Members } - #endregion + #endregion DataSources #region Archive Storage + /// /// Defines facilities for data storage when updating Zip Archives. /// @@ -3869,6 +4372,7 @@ public interface IArchiveStorage abstract public class BaseArchiveStorage : IArchiveStorage { #region Constructors + /// /// Initializes a new instance of the class. /// @@ -3877,7 +4381,8 @@ protected BaseArchiveStorage(FileUpdateMode updateMode) { updateMode_ = updateMode; } - #endregion + + #endregion Constructors #region IArchiveStorage Members @@ -3919,17 +4424,21 @@ protected BaseArchiveStorage(FileUpdateMode updateMode) /// Gets the update mode applicable. /// /// The update mode. - public FileUpdateMode UpdateMode { - get { + public FileUpdateMode UpdateMode + { + get + { return updateMode_; } } - #endregion + #endregion IArchiveStorage Members #region Instance Fields - FileUpdateMode updateMode_; - #endregion + + private readonly FileUpdateMode updateMode_; + + #endregion Instance Fields } /// @@ -3938,6 +4447,7 @@ public FileUpdateMode UpdateMode { public class DiskArchiveStorage : BaseArchiveStorage { #region Constructors + /// /// Initializes a new instance of the class. /// @@ -3946,7 +4456,8 @@ public class DiskArchiveStorage : BaseArchiveStorage public DiskArchiveStorage(ZipFile file, FileUpdateMode updateMode) : base(updateMode) { - if (file.Name == null) { + if (file.Name == null) + { throw new ZipException("Cant handle non file archives"); } @@ -3961,7 +4472,8 @@ public DiskArchiveStorage(ZipFile file) : this(file, FileUpdateMode.Safe) { } - #endregion + + #endregion Constructors #region IArchiveStorage Members @@ -3971,10 +4483,13 @@ public DiskArchiveStorage(ZipFile file) /// Returns the temporary output stream. public override Stream GetTemporaryOutput() { - if (temporaryName_ != null) { + if (temporaryName_ != null) + { temporaryName_ = GetTempFileName(temporaryName_, true); temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); - } else { + } + else + { // Determine where to place files based on internal strategy. // Currently this is always done in system temp directory. temporaryName_ = Path.GetTempFileName(); @@ -3991,7 +4506,8 @@ public override Stream GetTemporaryOutput() /// the final storage for the archive. public override Stream ConvertTemporaryToFinal() { - if (temporaryStream_ == null) { + if (temporaryStream_ == null) + { throw new ZipException("No temporary stream has been created"); } @@ -4000,7 +4516,8 @@ public override Stream ConvertTemporaryToFinal() string moveTempName = GetTempFileName(fileName_, false); bool newFileCreated = false; - try { + try + { temporaryStream_.Dispose(); File.Move(fileName_, moveTempName); File.Move(temporaryName_, fileName_); @@ -4008,11 +4525,14 @@ public override Stream ConvertTemporaryToFinal() File.Delete(moveTempName); result = File.Open(fileName_, FileMode.Open, FileAccess.Read, FileShare.Read); - } catch (Exception) { + } + catch (Exception) + { result = null; // Try to roll back changes... - if (!newFileCreated) { + if (!newFileCreated) + { File.Move(moveTempName, fileName_); File.Delete(temporaryName_); } @@ -4050,15 +4570,19 @@ public override Stream MakeTemporaryCopy(Stream stream) public override Stream OpenForDirectUpdate(Stream stream) { Stream result; - if ((stream == null) || !stream.CanWrite) { - if (stream != null) { + if ((stream == null) || !stream.CanWrite) + { + if (stream != null) + { stream.Dispose(); } result = new FileStream(fileName_, FileMode.Open, FileAccess.ReadWrite); - } else { + } + else + { result = stream; } @@ -4070,38 +4594,52 @@ public override Stream OpenForDirectUpdate(Stream stream) /// public override void Dispose() { - if (temporaryStream_ != null) { + if (temporaryStream_ != null) + { temporaryStream_.Dispose(); } } - #endregion + #endregion IArchiveStorage Members #region Internal routines - static string GetTempFileName(string original, bool makeTempFile) + + private static string GetTempFileName(string original, bool makeTempFile) { string result = null; - if (original == null) { + if (original == null) + { result = Path.GetTempFileName(); - } else { + } + else + { int counter = 0; int suffixSeed = DateTime.Now.Second; - while (result == null) { + while (result == null) + { counter += 1; string newName = string.Format("{0}.{1}{2}.tmp", original, suffixSeed, counter); - if (!File.Exists(newName)) { - if (makeTempFile) { - try { + if (!File.Exists(newName)) + { + if (makeTempFile) + { + try + { // Try and create the file. - using (FileStream stream = File.Create(newName)) { + using (FileStream stream = File.Create(newName)) + { } result = newName; - } catch { + } + catch + { suffixSeed = DateTime.Now.Second; } - } else { + } + else + { result = newName; } } @@ -4109,13 +4647,16 @@ static string GetTempFileName(string original, bool makeTempFile) } return result; } - #endregion + + #endregion Internal routines #region Instance Fields - Stream temporaryStream_; - string fileName_; - string temporaryName_; - #endregion + + private Stream temporaryStream_; + private readonly string fileName_; + private string temporaryName_; + + #endregion Instance Fields } /// @@ -4124,6 +4665,7 @@ static string GetTempFileName(string original, bool makeTempFile) public class MemoryArchiveStorage : BaseArchiveStorage { #region Constructors + /// /// Initializes a new instance of the class. /// @@ -4142,17 +4684,19 @@ public MemoryArchiveStorage(FileUpdateMode updateMode) { } - #endregion + #endregion Constructors #region Properties + /// /// Get the stream returned by if this was in fact called. /// - public MemoryStream FinalStream { + public MemoryStream FinalStream + { get { return finalStream_; } } - #endregion + #endregion Properties #region IArchiveStorage Members @@ -4173,7 +4717,8 @@ public override Stream GetTemporaryOutput() /// the final storage for the archive. public override Stream ConvertTemporaryToFinal() { - if (temporaryStream_ == null) { + if (temporaryStream_ == null) + { throw new ZipException("No temporary stream has been created"); } @@ -4204,17 +4749,20 @@ public override Stream MakeTemporaryCopy(Stream stream) public override Stream OpenForDirectUpdate(Stream stream) { Stream result; - if ((stream == null) || !stream.CanWrite) { - + if ((stream == null) || !stream.CanWrite) + { result = new MemoryStream(); - if (stream != null) { + if (stream != null) + { stream.Position = 0; StreamUtils.Copy(stream, result, new byte[4096]); stream.Dispose(); } - } else { + } + else + { result = stream; } @@ -4226,18 +4774,21 @@ public override Stream OpenForDirectUpdate(Stream stream) /// public override void Dispose() { - if (temporaryStream_ != null) { + if (temporaryStream_ != null) + { temporaryStream_.Dispose(); } } - #endregion + #endregion IArchiveStorage Members #region Instance Fields - MemoryStream temporaryStream_; - MemoryStream finalStream_; - #endregion + + private MemoryStream temporaryStream_; + private MemoryStream finalStream_; + + #endregion Instance Fields } - #endregion + #endregion Archive Storage } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs index f00593d37..03567b3bf 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Text; namespace ICSharpCode.SharpZipLib.Zip { @@ -12,7 +11,8 @@ public class DescriptorData /// /// Get /set the compressed size of data. /// - public long CompressedSize { + public long CompressedSize + { get { return compressedSize; } set { compressedSize = value; } } @@ -20,7 +20,8 @@ public long CompressedSize { /// /// Get / set the uncompressed size of data /// - public long Size { + public long Size + { get { return size; } set { size = value; } } @@ -28,34 +29,41 @@ public long Size { /// /// Get /set the crc value. /// - public long Crc { + public long Crc + { get { return crc; } set { crc = (value & 0xffffffff); } } #region Instance Fields - long size; - long compressedSize; - long crc; - #endregion + + private long size; + private long compressedSize; + private long crc; + + #endregion Instance Fields } - class EntryPatchData + internal class EntryPatchData { - public long SizePatchOffset { + public long SizePatchOffset + { get { return sizePatchOffset_; } set { sizePatchOffset_ = value; } } - public long CrcPatchOffset { + public long CrcPatchOffset + { get { return crcPatchOffset_; } set { crcPatchOffset_ = value; } } #region Instance Fields - long sizePatchOffset_; - long crcPatchOffset_; - #endregion + + private long sizePatchOffset_; + private long crcPatchOffset_; + + #endregion Instance Fields } /// @@ -64,6 +72,7 @@ public long CrcPatchOffset { internal class ZipHelperStream : Stream { #region Constructors + /// /// Initialise an instance of this class. /// @@ -82,40 +91,49 @@ public ZipHelperStream(Stream stream) { stream_ = stream; } - #endregion + + #endregion Constructors /// /// Get / set a value indicating wether the the underlying stream is owned or not. /// /// If the stream is owned it is closed when this instance is closed. - public bool IsStreamOwner { + public bool IsStreamOwner + { get { return isOwner_; } set { isOwner_ = value; } } #region Base Stream Methods - public override bool CanRead { + + public override bool CanRead + { get { return stream_.CanRead; } } - public override bool CanSeek { + public override bool CanSeek + { get { return stream_.CanSeek; } } - public override bool CanTimeout { + public override bool CanTimeout + { get { return stream_.CanTimeout; } } - public override long Length { + public override long Length + { get { return stream_.Length; } } - public override long Position { + public override long Position + { get { return stream_.Position; } set { stream_.Position = value; } } - public override bool CanWrite { + public override bool CanWrite + { get { return stream_.CanWrite; } } @@ -154,17 +172,18 @@ protected override void Dispose(bool disposing) { Stream toClose = stream_; stream_ = null; - if (isOwner_ && (toClose != null)) { + if (isOwner_ && (toClose != null)) + { isOwner_ = false; toClose.Dispose(); } } - #endregion + #endregion Base Stream Methods // Write the local file header // TODO: ZipHelperStream.WriteLocalHeader is not yet used and needs checking for ZipFile and ZipOuptutStream usage - void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) + private void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) { CompressionMethod method = entry.CompressionMethod; bool headerInfoAvailable = true; // How to get this? @@ -177,62 +196,82 @@ void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) WriteLEShort((byte)method); WriteLEInt((int)entry.DosTime); - if (headerInfoAvailable == true) { + if (headerInfoAvailable == true) + { WriteLEInt((int)entry.Crc); - if (entry.LocalHeaderRequiresZip64) { + if (entry.LocalHeaderRequiresZip64) + { WriteLEInt(-1); WriteLEInt(-1); - } else { + } + else + { WriteLEInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLEInt((int)entry.Size); } - } else { - if (patchData != null) { + } + else + { + if (patchData != null) + { patchData.CrcPatchOffset = stream_.Position; } WriteLEInt(0); // Crc - if (patchData != null) { + if (patchData != null) + { patchData.SizePatchOffset = stream_.Position; } // For local header both sizes appear in Zip64 Extended Information - if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { + if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) + { WriteLEInt(-1); WriteLEInt(-1); - } else { + } + else + { WriteLEInt(0); // Compressed size WriteLEInt(0); // Uncompressed size } } - byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); + byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name); - if (name.Length > 0xFFFF) { + if (name.Length > 0xFFFF) + { throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); - if (entry.LocalHeaderRequiresZip64 && (headerInfoAvailable || patchEntryHeader)) { + if (entry.LocalHeaderRequiresZip64 && (headerInfoAvailable || patchEntryHeader)) + { ed.StartNewEntry(); - if (headerInfoAvailable) { + if (headerInfoAvailable) + { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); - } else { + } + else + { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); - if (!ed.Find(1)) { + if (!ed.Find(1)) + { throw new ZipException("Internal error cant find extra data"); } - if (patchData != null) { + if (patchData != null) + { patchData.SizePatchOffset = ed.CurrentReadIndex; } - } else { + } + else + { ed.Delete(1); } @@ -241,15 +280,18 @@ void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) WriteLEShort(name.Length); WriteLEShort(extra.Length); - if (name.Length > 0) { + if (name.Length > 0) + { stream_.Write(name, 0, name.Length); } - if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { + if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) + { patchData.SizePatchOffset += stream_.Position; } - if (extra.Length > 0) { + if (extra.Length > 0) + { stream_.Write(extra, 0, extra.Length); } } @@ -265,15 +307,18 @@ void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) public long LocateBlockWithSignature(int signature, long endLocation, int minimumBlockSize, int maximumVariableData) { long pos = endLocation - minimumBlockSize; - if (pos < 0) { + if (pos < 0) + { return -1; } long giveUpMarker = Math.Max(pos - maximumVariableData, 0); // TODO: This loop could be optimised for speed. - do { - if (pos < giveUpMarker) { + do + { + if (pos < giveUpMarker) + { return -1; } Seek(pos--, SeekOrigin.Begin); @@ -326,10 +371,10 @@ public void WriteZip64EndOfCentralDirectory(long noOfEntries, long sizeEntries, public void WriteEndOfCentralDirectory(long noOfEntries, long sizeEntries, long startOfCentralDirectory, byte[] comment) { - if ((noOfEntries >= 0xffff) || (startOfCentralDirectory >= 0xffffffff) || - (sizeEntries >= 0xffffffff)) { + (sizeEntries >= 0xffffffff)) + { WriteZip64EndOfCentralDirectory(noOfEntries, sizeEntries, startOfCentralDirectory); } @@ -339,45 +384,55 @@ public void WriteEndOfCentralDirectory(long noOfEntries, long sizeEntries, WriteLEShort(0); // number of this disk WriteLEShort(0); // no of disk with start of central dir - // Number of entries - if (noOfEntries >= 0xffff) { + if (noOfEntries >= 0xffff) + { WriteLEUshort(0xffff); // Zip64 marker WriteLEUshort(0xffff); - } else { + } + else + { WriteLEShort((short)noOfEntries); // entries in central dir for this disk WriteLEShort((short)noOfEntries); // total entries in central directory } // Size of the central directory - if (sizeEntries >= 0xffffffff) { + if (sizeEntries >= 0xffffffff) + { WriteLEUint(0xffffffff); // Zip64 marker - } else { + } + else + { WriteLEInt((int)sizeEntries); } - // offset of start of central directory - if (startOfCentralDirectory >= 0xffffffff) { + if (startOfCentralDirectory >= 0xffffffff) + { WriteLEUint(0xffffffff); // Zip64 marker - } else { + } + else + { WriteLEInt((int)startOfCentralDirectory); } int commentLength = (comment != null) ? comment.Length : 0; - if (commentLength > 0xffff) { + if (commentLength > 0xffff) + { throw new ZipException(string.Format("Comment length({0}) is too long can only be 64K", commentLength)); } WriteLEShort(commentLength); - if (commentLength > 0) { + if (commentLength > 0) + { Write(comment, 0, comment.Length); } } #region LE value reading/writing + /// /// Read an unsigned short in little endian byte order. /// @@ -392,12 +447,14 @@ public int ReadLEShort() { int byteValue1 = stream_.ReadByte(); - if (byteValue1 < 0) { + if (byteValue1 < 0) + { throw new EndOfStreamException(); } int byteValue2 = stream_.ReadByte(); - if (byteValue2 < 0) { + if (byteValue2 < 0) + { throw new EndOfStreamException(); } @@ -488,7 +545,7 @@ public void WriteLEUlong(ulong value) WriteLEUint((uint)(value >> 32)); } - #endregion + #endregion LE value reading/writing /// /// Write a data descriptor. @@ -497,14 +554,16 @@ public void WriteLEUlong(ulong value) /// Returns the number of descriptor bytes written. public int WriteDataDescriptor(ZipEntry entry) { - if (entry == null) { + if (entry == null) + { throw new ArgumentNullException(nameof(entry)); } int result = 0; // Add data descriptor if flagged as required - if ((entry.Flags & (int)GeneralBitFlags.Descriptor) != 0) { + if ((entry.Flags & (int)GeneralBitFlags.Descriptor) != 0) + { // The signature is not PKZIP originally but is now described as optional // in the PKZIP Appnote documenting trhe format. WriteLEInt(ZipConstants.DataDescriptorSignature); @@ -512,11 +571,14 @@ public int WriteDataDescriptor(ZipEntry entry) result += 8; - if (entry.LocalHeaderRequiresZip64) { + if (entry.LocalHeaderRequiresZip64) + { WriteLELong(entry.CompressedSize); WriteLELong(entry.Size); result += 16; - } else { + } + else + { WriteLEInt((int)entry.CompressedSize); WriteLEInt((int)entry.Size); result += 8; @@ -538,24 +600,30 @@ public void ReadDataDescriptor(bool zip64, DescriptorData data) // In theory this may not be a descriptor according to PKZIP appnote. // In practise its always there. - if (intValue != ZipConstants.DataDescriptorSignature) { + if (intValue != ZipConstants.DataDescriptorSignature) + { throw new ZipException("Data descriptor signature not found"); } data.Crc = ReadLEInt(); - if (zip64) { + if (zip64) + { data.CompressedSize = ReadLELong(); data.Size = ReadLELong(); - } else { + } + else + { data.CompressedSize = ReadLEInt(); data.Size = ReadLEInt(); } } #region Instance Fields - bool isOwner_; - Stream stream_; - #endregion + + private bool isOwner_; + private Stream stream_; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs index 01889409a..fc783caa0 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs @@ -1,9 +1,9 @@ -using System; -using System.IO; using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Encryption; using ICSharpCode.SharpZipLib.Zip.Compression; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Zip { @@ -16,15 +16,15 @@ namespace ICSharpCode.SharpZipLib.Zip ///
///
Author of the original java version : Jochen Hoenicke ///
- /// + /// /// This sample shows how to read a zip file /// /// using System; /// using System.Text; /// using System.IO; - /// + /// /// using ICSharpCode.SharpZipLib.Zip; - /// + /// /// class MainClass /// { /// public static void Main(string[] args) @@ -34,7 +34,7 @@ namespace ICSharpCode.SharpZipLib.Zip /// ZipEntry theEntry; /// const int size = 2048; /// byte[] data = new byte[2048]; - /// + /// /// while ((theEntry = s.GetNextEntry()) != null) { /// if ( entry.IsFile ) { /// Console.Write("Show contents (y/n) ?"); @@ -60,25 +60,27 @@ public class ZipInputStream : InflaterInputStream #region Instance Fields /// - /// Delegate for reading bytes from a stream. + /// Delegate for reading bytes from a stream. /// - delegate int ReadDataHandler(byte[] b, int offset, int length); + private delegate int ReadDataHandler(byte[] b, int offset, int length); /// /// The current reader this instance. /// - ReadDataHandler internalReader; + private ReadDataHandler internalReader; - Crc32 crc = new Crc32(); - ZipEntry entry; + private Crc32 crc = new Crc32(); + private ZipEntry entry; - long size; - int method; - int flags; - string password; - #endregion + private long size; + private int method; + private int flags; + private string password; + + #endregion Instance Fields #region Constructors + /// /// Creates a new Zip input stream, for reading a zip archive. /// @@ -99,22 +101,25 @@ public ZipInputStream(Stream baseInputStream, int bufferSize) { internalReader = new ReadDataHandler(ReadingNotAvailable); } - #endregion + + #endregion Constructors /// /// Optional password used for encryption when non-null /// /// A password for all encrypted entries in this - public string Password { - get { + public string Password + { + get + { return password; } - set { + set + { password = value; } } - /// /// Gets a value indicating if there is a current entry and it can be decompressed /// @@ -122,8 +127,10 @@ public string Password { /// The entry can only be decompressed if the library supports the zip features required to extract it. /// See the ZipEntry Version property for more details. /// - public bool CanDecompressEntry { - get { + public bool CanDecompressEntry + { + get + { return (entry != null) && entry.CanDecompress; } } @@ -146,11 +153,13 @@ public bool CanDecompressEntry { /// public ZipEntry GetNextEntry() { - if (crc == null) { + if (crc == null) + { throw new InvalidOperationException("Closed."); } - if (entry != null) { + if (entry != null) + { CloseEntry(); } @@ -160,7 +169,8 @@ public ZipEntry GetNextEntry() header == ZipConstants.EndOfCentralDirectorySignature || header == ZipConstants.CentralHeaderDigitalSignature || header == ZipConstants.ArchiveExtraDataSignature || - header == ZipConstants.Zip64CentralFileHeaderSignature) { + header == ZipConstants.Zip64CentralFileHeaderSignature) + { // No more individual entries exist Dispose(); return null; @@ -168,11 +178,13 @@ public ZipEntry GetNextEntry() // -jr- 07-Dec-2003 Ignore spanning temporary signatures if found // Spanning signature is same as descriptor signature and is untested as yet. - if ((header == ZipConstants.SpanningTempSignature) || (header == ZipConstants.SpanningSignature)) { + if ((header == ZipConstants.SpanningTempSignature) || (header == ZipConstants.SpanningSignature)) + { header = inputBuffer.ReadLeInt(); } - if (header != ZipConstants.LocalHeaderSignature) { + if (header != ZipConstants.LocalHeaderSignature) + { throw new ZipException("Wrong Local header signature: 0x" + String.Format("{0:X}", header)); } @@ -192,33 +204,38 @@ public ZipEntry GetNextEntry() byte[] buffer = new byte[nameLen]; inputBuffer.ReadRawBuffer(buffer); - string name = ZipConstants.ConvertToStringExt(flags, buffer); - - entry = new ZipEntry(name, versionRequiredToExtract); - entry.Flags = flags; + string name = ZipStrings.ConvertToStringExt(flags, buffer); - entry.CompressionMethod = (CompressionMethod)method; + entry = new ZipEntry(name, versionRequiredToExtract) + { + Flags = flags, + CompressionMethod = (CompressionMethod)method + }; - if ((flags & 8) == 0) { + if ((flags & 8) == 0) + { entry.Crc = crc2 & 0xFFFFFFFFL; entry.Size = size & 0xFFFFFFFFL; entry.CompressedSize = csize & 0xFFFFFFFFL; entry.CryptoCheckValue = (byte)((crc2 >> 24) & 0xff); - - } else { - + } + else + { // This allows for GNU, WinZip and possibly other archives, the PKZIP spec // says these values are zero under these circumstances. - if (crc2 != 0) { + if (crc2 != 0) + { entry.Crc = crc2 & 0xFFFFFFFFL; } - if (size != 0) { + if (size != 0) + { entry.Size = size & 0xFFFFFFFFL; } - if (csize != 0) { + if (csize != 0) + { entry.CompressedSize = csize & 0xFFFFFFFFL; } @@ -231,29 +248,36 @@ public ZipEntry GetNextEntry() // both values. // Handle extra data if present. This can set/alter some fields of the entry. - if (extraLen > 0) { + if (extraLen > 0) + { byte[] extra = new byte[extraLen]; inputBuffer.ReadRawBuffer(extra); entry.ExtraData = extra; } entry.ProcessExtraData(true); - if (entry.CompressedSize >= 0) { + if (entry.CompressedSize >= 0) + { csize = entry.CompressedSize; } - if (entry.Size >= 0) { + if (entry.Size >= 0) + { size = entry.Size; } - if (method == (int)CompressionMethod.Stored && (!isCrypted && csize != size || (isCrypted && csize - ZipConstants.CryptoHeaderSize != size))) { + if (method == (int)CompressionMethod.Stored && (!isCrypted && csize != size || (isCrypted && csize - ZipConstants.CryptoHeaderSize != size))) + { throw new ZipException("Stored, but compressed != uncompressed"); } // Determine how to handle reading of data if this is attempted. - if (entry.IsCompressionMethodSupported()) { + if (entry.IsCompressionMethodSupported()) + { internalReader = new ReadDataHandler(InitialRead); - } else { + } + else + { internalReader = new ReadDataHandler(ReadingNotSupported); } @@ -261,20 +285,24 @@ public ZipEntry GetNextEntry() } /// - /// Read data descriptor at the end of compressed data. + /// Read data descriptor at the end of compressed data. /// - void ReadDataDescriptor() + private void ReadDataDescriptor() { - if (inputBuffer.ReadLeInt() != ZipConstants.DataDescriptorSignature) { + if (inputBuffer.ReadLeInt() != ZipConstants.DataDescriptorSignature) + { throw new ZipException("Data descriptor signature not found"); } entry.Crc = inputBuffer.ReadLeInt() & 0xFFFFFFFFL; - if (entry.LocalHeaderRequiresZip64) { + if (entry.LocalHeaderRequiresZip64) + { csize = inputBuffer.ReadLeLong(); size = inputBuffer.ReadLeLong(); - } else { + } + else + { csize = inputBuffer.ReadLeInt(); size = inputBuffer.ReadLeInt(); } @@ -286,24 +314,27 @@ void ReadDataDescriptor() /// Complete cleanup as the final part of closing. ///
/// True if the crc value should be tested - void CompleteCloseEntry(bool testCrc) + private void CompleteCloseEntry(bool testCrc) { StopDecrypting(); - if ((flags & 8) != 0) { + if ((flags & 8) != 0) + { ReadDataDescriptor(); } size = 0; if (testCrc && - ((crc.Value & 0xFFFFFFFFL) != entry.Crc) && (entry.Crc != -1)) { + ((crc.Value & 0xFFFFFFFFL) != entry.Crc) && (entry.Crc != -1)) + { throw new ZipException("CRC mismatch"); } crc.Reset(); - if (method == (int)CompressionMethod.Deflated) { + if (method == (int)CompressionMethod.Deflated) + { inf.Reset(); } entry = null; @@ -320,21 +351,26 @@ void CompleteCloseEntry(bool testCrc) /// public void CloseEntry() { - if (crc == null) { + if (crc == null) + { throw new InvalidOperationException("Closed"); } - if (entry == null) { + if (entry == null) + { return; } - if (method == (int)CompressionMethod.Deflated) { - if ((flags & 8) != 0) { + if (method == (int)CompressionMethod.Deflated) + { + if ((flags & 8) != 0) + { // We don't know how much we must skip, read until end. byte[] tmp = new byte[4096]; // Read will close this entry - while (Read(tmp, 0, tmp.Length) > 0) { + while (Read(tmp, 0, tmp.Length) > 0) + { } return; } @@ -343,15 +379,20 @@ public void CloseEntry() inputBuffer.Available += inf.RemainingInput; } - if ((inputBuffer.Available > csize) && (csize >= 0)) { + if ((inputBuffer.Available > csize) && (csize >= 0)) + { inputBuffer.Available = (int)((long)inputBuffer.Available - csize); - } else { + } + else + { csize -= inputBuffer.Available; inputBuffer.Available = 0; - while (csize != 0) { + while (csize != 0) + { long skipped = Skip(csize); - if (skipped <= 0) { + if (skipped <= 0) + { throw new ZipException("Zip archive ends early."); } @@ -366,8 +407,10 @@ public void CloseEntry() /// Returns 1 if there is an entry available /// Otherwise returns 0. /// - public override int Available { - get { + public override int Available + { + get + { return entry != null ? 1 : 0; } } @@ -377,19 +420,26 @@ public override int Available { /// /// Thrown if the entry size is not known. /// Thrown if no entry is currently available. - public override long Length { - get { - if (entry != null) { - if (entry.Size >= 0) { + public override long Length + { + get + { + if (entry != null) + { + if (entry.Size >= 0) + { return entry.Size; - } else { + } + else + { throw new ZipException("Length not available for the current entry"); } - } else { + } + else + { throw new InvalidOperationException("No current entry"); } } - } /// @@ -401,7 +451,8 @@ public override long Length { public override int ReadByte() { byte[] b = new byte[1]; - if (Read(b, 0, 1) <= 0) { + if (Read(b, 0, 1) <= 0) + { return -1; } return b[0] & 0xff; @@ -414,7 +465,7 @@ public override int ReadByte() /// The offset at which data read should be stored. /// The maximum number of bytes to read. /// Returns the number of bytes actually read. - int ReadingNotAvailable(byte[] destination, int offset, int count) + private int ReadingNotAvailable(byte[] destination, int offset, int count) { throw new InvalidOperationException("Unable to read from this stream"); } @@ -422,61 +473,74 @@ int ReadingNotAvailable(byte[] destination, int offset, int count) /// /// Handle attempts to read from this entry by throwing an exception /// - int ReadingNotSupported(byte[] destination, int offset, int count) + private int ReadingNotSupported(byte[] destination, int offset, int count) { throw new ZipException("The compression method for this entry is not supported"); } /// - /// Perform the initial read on an entry which may include + /// Perform the initial read on an entry which may include /// reading encryption headers and setting up inflation. /// /// The destination to fill with data read. /// The offset to start reading at. /// The maximum number of bytes to read. /// The actual number of bytes read. - int InitialRead(byte[] destination, int offset, int count) + private int InitialRead(byte[] destination, int offset, int count) { - if (!CanDecompressEntry) { + if (!CanDecompressEntry) + { throw new ZipException("Library cannot extract this entry. Version required is (" + entry.Version + ")"); } // Handle encryption if required. - if (entry.IsCrypted) { - if (password == null) { + if (entry.IsCrypted) + { + if (password == null) + { throw new ZipException("No password set."); } // Generate and set crypto transform... var managed = new PkzipClassicManaged(); - byte[] key = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(password)); + byte[] key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(password)); inputBuffer.CryptoTransform = managed.CreateDecryptor(key, null); byte[] cryptbuffer = new byte[ZipConstants.CryptoHeaderSize]; inputBuffer.ReadClearTextBuffer(cryptbuffer, 0, ZipConstants.CryptoHeaderSize); - if (cryptbuffer[ZipConstants.CryptoHeaderSize - 1] != entry.CryptoCheckValue) { + if (cryptbuffer[ZipConstants.CryptoHeaderSize - 1] != entry.CryptoCheckValue) + { throw new ZipException("Invalid password"); } - if (csize >= ZipConstants.CryptoHeaderSize) { + if (csize >= ZipConstants.CryptoHeaderSize) + { csize -= ZipConstants.CryptoHeaderSize; - } else if ((entry.Flags & (int)GeneralBitFlags.Descriptor) == 0) { + } + else if ((entry.Flags & (int)GeneralBitFlags.Descriptor) == 0) + { throw new ZipException(string.Format("Entry compressed size {0} too small for encryption", csize)); } - } else { + } + else + { inputBuffer.CryptoTransform = null; } - if ((csize > 0) || ((flags & (int)GeneralBitFlags.Descriptor) != 0)) { - if ((method == (int)CompressionMethod.Deflated) && (inputBuffer.Available > 0)) { + if ((csize > 0) || ((flags & (int)GeneralBitFlags.Descriptor) != 0)) + { + if ((method == (int)CompressionMethod.Deflated) && (inputBuffer.Available > 0)) + { inputBuffer.SetInflaterInput(inf); } internalReader = new ReadDataHandler(BodyRead); return BodyRead(destination, offset, count); - } else { + } + else + { internalReader = new ReadDataHandler(ReadingNotAvailable); return 0; } @@ -492,19 +556,23 @@ int InitialRead(byte[] destination, int offset, int count) /// Zero bytes read means end of stream. public override int Read(byte[] buffer, int offset, int count) { - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset), "Cannot be negative"); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count), "Cannot be negative"); } - if ((buffer.Length - offset) < count) { + if ((buffer.Length - offset) < count) + { throw new ArgumentException("Invalid offset/count combination"); } @@ -526,34 +594,41 @@ public override int Read(byte[] buffer, int offset, int count) /// /// The stream is not open. /// - int BodyRead(byte[] buffer, int offset, int count) + private int BodyRead(byte[] buffer, int offset, int count) { - if (crc == null) { + if (crc == null) + { throw new InvalidOperationException("Closed"); } - if ((entry == null) || (count <= 0)) { + if ((entry == null) || (count <= 0)) + { return 0; } - if (offset + count > buffer.Length) { + if (offset + count > buffer.Length) + { throw new ArgumentException("Offset + count exceeds buffer size"); } bool finished = false; - switch (method) { + switch (method) + { case (int)CompressionMethod.Deflated: count = base.Read(buffer, offset, count); - if (count <= 0) { - if (!inf.IsFinished) { + if (count <= 0) + { + if (!inf.IsFinished) + { throw new ZipException("Inflater not finished!"); } inputBuffer.Available = inf.RemainingInput; // A csize of -1 is from an unpatched local header if ((flags & 8) == 0 && - (inf.TotalIn != csize && csize != 0xFFFFFFFF && csize != -1 || inf.TotalOut != size)) { + (inf.TotalIn != csize && csize != 0xFFFFFFFF && csize != -1 || inf.TotalOut != size)) + { throw new ZipException("Size mismatch: " + csize + ";" + size + " <-> " + inf.TotalIn + ";" + inf.TotalOut); } inf.Reset(); @@ -562,33 +637,42 @@ int BodyRead(byte[] buffer, int offset, int count) break; case (int)CompressionMethod.Stored: - if ((count > csize) && (csize >= 0)) { + if ((count > csize) && (csize >= 0)) + { count = (int)csize; } - if (count > 0) { + if (count > 0) + { count = inputBuffer.ReadClearTextBuffer(buffer, offset, count); - if (count > 0) { + if (count > 0) + { csize -= count; size -= count; } } - if (csize == 0) { + if (csize == 0) + { finished = true; - } else { - if (count < 0) { + } + else + { + if (count < 0) + { throw new ZipException("EOF in stored block"); } } break; } - if (count > 0) { + if (count > 0) + { crc.Update(new ArraySegment(buffer, offset, count)); } - if (finished) { + if (finished) + { CompleteCloseEntry(true); } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs index e2315a298..1b5e01a68 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs @@ -1,18 +1,19 @@ +using ICSharpCode.SharpZipLib.Core; using System; using System.IO; using System.Text; -using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.Zip { /// /// ZipNameTransform transforms names as per the Zip file naming convention. /// - /// The use of absolute names is supported although its use is not valid + /// The use of absolute names is supported although its use is not valid /// according to Zip naming conventions, and should not be used if maximum compatability is desired. public class ZipNameTransform : INameTransform { #region Constructors + /// /// Initialize a new instance of /// @@ -28,7 +29,8 @@ public ZipNameTransform(string trimPrefix) { TrimPrefix = trimPrefix; } - #endregion + + #endregion Constructors /// /// Static constructor. @@ -61,11 +63,15 @@ static ZipNameTransform() public string TransformDirectory(string name) { name = TransformFile(name); - if (name.Length > 0) { - if (!name.EndsWith("/", StringComparison.Ordinal)) { + if (name.Length > 0) + { + if (!name.EndsWith("/", StringComparison.Ordinal)) + { name += "/"; } - } else { + } + else + { throw new ZipException("Cannot have an empty directory name"); } return name; @@ -78,9 +84,11 @@ public string TransformDirectory(string name) /// The transformed name. public string TransformFile(string name) { - if (name != null) { + if (name != null) + { string lowerName = name.ToLower(); - if ((trimPrefix_ != null) && (lowerName.IndexOf(trimPrefix_, StringComparison.Ordinal) == 0)) { + if ((trimPrefix_ != null) && (lowerName.IndexOf(trimPrefix_, StringComparison.Ordinal) == 0)) + { name = name.Substring(trimPrefix_.Length); } @@ -88,24 +96,29 @@ public string TransformFile(string name) name = WindowsPathUtils.DropPathRoot(name); // Drop any leading slashes. - while ((name.Length > 0) && (name[0] == '/')) { + while ((name.Length > 0) && (name[0] == '/')) + { name = name.Remove(0, 1); } // Drop any trailing slashes. - while ((name.Length > 0) && (name[name.Length - 1] == '/')) { + while ((name.Length > 0) && (name[name.Length - 1] == '/')) + { name = name.Remove(name.Length - 1, 1); } // Convert consecutive // characters to / int index = name.IndexOf("//", StringComparison.Ordinal); - while (index >= 0) { + while (index >= 0) + { name = name.Remove(index, 1); index = name.IndexOf("//", StringComparison.Ordinal); } name = MakeValidName(name, '_'); - } else { + } + else + { name = string.Empty; } return name; @@ -116,11 +129,14 @@ public string TransformFile(string name) /// /// The prefix is trimmed before any conversion from /// a windows path is done. - public string TrimPrefix { + public string TrimPrefix + { get { return trimPrefix_; } - set { + set + { trimPrefix_ = value; - if (trimPrefix_ != null) { + if (trimPrefix_ != null) + { trimPrefix_ = trimPrefix_.ToLower(); } } @@ -132,25 +148,31 @@ public string TrimPrefix { /// The name to force valid /// The replacement character to use. /// Returns a valid name - static string MakeValidName(string name, char replacement) + private static string MakeValidName(string name, char replacement) { int index = name.IndexOfAny(InvalidEntryChars); - if (index >= 0) { + if (index >= 0) + { var builder = new StringBuilder(name); - while (index >= 0) { + while (index >= 0) + { builder[index] = replacement; - if (index >= name.Length) { + if (index >= name.Length) + { index = -1; - } else { + } + else + { index = name.IndexOfAny(InvalidEntryChars, index + 1); } } name = builder.ToString(); } - if (name.Length > 0xffff) { + if (name.Length > 0xffff) + { throw new PathTooLongException(); } @@ -173,10 +195,14 @@ public static bool IsValidName(string name, bool relaxed) { bool result = (name != null); - if (result) { - if (relaxed) { + if (result) + { + if (relaxed) + { result = name.IndexOfAny(InvalidEntryCharsRelaxed) < 0; - } else { + } + else + { result = (name.IndexOfAny(InvalidEntryChars) < 0) && (name.IndexOf('/') != 0); @@ -209,12 +235,16 @@ public static bool IsValidName(string name) } #region Instance Fields - string trimPrefix_; - #endregion + + private string trimPrefix_; + + #endregion Instance Fields #region Class Fields - static readonly char[] InvalidEntryChars; - static readonly char[] InvalidEntryCharsRelaxed; - #endregion + + private static readonly char[] InvalidEntryChars; + private static readonly char[] InvalidEntryCharsRelaxed; + + #endregion Class Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs index f62a7ecff..88c810393 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs @@ -1,10 +1,9 @@ -using System; -using System.IO; -using System.Collections; using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Zip.Compression; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using System; using System.Collections.Generic; +using System.IO; namespace ICSharpCode.SharpZipLib.Zip { @@ -13,7 +12,7 @@ namespace ICSharpCode.SharpZipLib.Zip /// archive one after another. It has a special method to start a new /// zip entry. The zip entries contains information about the file name /// size, compressed size, CRC, etc. - /// + /// /// It includes support for Stored and Deflated entries. /// This class is not thread safe. ///
@@ -23,21 +22,21 @@ namespace ICSharpCode.SharpZipLib.Zip /// /// using System; /// using System.IO; - /// + /// /// using ICSharpCode.SharpZipLib.Core; /// using ICSharpCode.SharpZipLib.Zip; - /// + /// /// class MainClass /// { /// public static void Main(string[] args) /// { /// string[] filenames = Directory.GetFiles(args[0]); /// byte[] buffer = new byte[4096]; - /// + /// /// using ( ZipOutputStream s = new ZipOutputStream(File.Create(args[1])) ) { - /// + /// /// s.SetLevel(9); // 0 - store only to 9 - means best compression - /// + /// /// foreach (string file in filenames) { /// ZipEntry entry = new ZipEntry(file); /// s.PutNextEntry(entry); @@ -48,12 +47,13 @@ namespace ICSharpCode.SharpZipLib.Zip /// } /// } /// } - /// } + /// } /// /// public class ZipOutputStream : DeflaterOutputStream { #region Constructors + /// /// Creates a new Zip output stream, writing a zip archive. /// @@ -74,14 +74,17 @@ public ZipOutputStream(Stream baseOutputStream, int bufferSize) : base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true), bufferSize) { } - #endregion + + #endregion Constructors /// /// Gets a flag value of true if the central header has been added for this archive; false if it has not been added. /// /// No further entries can be added once this has been done. - public bool IsFinished { - get { + public bool IsFinished + { + get + { return entries == null; } } @@ -99,7 +102,8 @@ public void SetComment(string comment) { // TODO: Its not yet clear how to handle unicode comments here. byte[] commentBytes = ZipStrings.ConvertToArray(comment); - if (commentBytes.Length > 0xffff) { + if (commentBytes.Length > 0xffff) + { throw new ArgumentOutOfRangeException(nameof(comment)); } zipComment = commentBytes; @@ -136,7 +140,8 @@ public int GetLevel() /// If backwards compatability is an issue be careful when adding entries to an archive. /// Setting this property to off is workable but less desirable as in those circumstances adding a file /// larger then 4GB will fail.
- public UseZip64 UseZip64 { + public UseZip64 UseZip64 + { get { return useZip64_; } set { useZip64_ = value; } } @@ -146,7 +151,8 @@ public UseZip64 UseZip64 { ///
private void WriteLeShort(int value) { - unchecked { + unchecked + { baseOutputStream_.WriteByte((byte)(value & 0xff)); baseOutputStream_.WriteByte((byte)((value >> 8) & 0xff)); } @@ -157,7 +163,8 @@ private void WriteLeShort(int value) /// private void WriteLeInt(int value) { - unchecked { + unchecked + { WriteLeShort(value); WriteLeShort(value >> 16); } @@ -168,7 +175,8 @@ private void WriteLeInt(int value) /// private void WriteLeLong(long value) { - unchecked { + unchecked + { WriteLeInt((int)value); WriteLeInt((int)(value >> 32)); } @@ -200,19 +208,23 @@ private void WriteLeLong(long value) /// public void PutNextEntry(ZipEntry entry) { - if (entry == null) { + if (entry == null) + { throw new ArgumentNullException(nameof(entry)); } - if (entries == null) { + if (entries == null) + { throw new InvalidOperationException("ZipOutputStream was finished"); } - if (curEntry != null) { + if (curEntry != null) + { CloseEntry(); } - if (entries.Count == int.MaxValue) { + if (entries.Count == int.MaxValue) + { throw new ZipException("Too many entries for Zip file"); } @@ -226,45 +238,58 @@ public void PutNextEntry(ZipEntry entry) bool headerInfoAvailable; // No need to compress - definitely no data. - if (entry.Size == 0) { + if (entry.Size == 0) + { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; - } else { + } + else + { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc && entry.CompressedSize >= 0; // Switch to deflation if storing isnt possible. - if (method == CompressionMethod.Stored) { - if (!headerInfoAvailable) { - if (!CanPatchEntries) { + if (method == CompressionMethod.Stored) + { + if (!headerInfoAvailable) + { + if (!CanPatchEntries) + { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } - } else // entry.size must be > 0 - { + } + else // entry.size must be > 0 + { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } - if (headerInfoAvailable == false) { - if (CanPatchEntries == false) { + if (headerInfoAvailable == false) + { + if (CanPatchEntries == false) + { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; - } else { + } + else + { patchEntryHeader = true; } } - if (Password != null) { + if (Password != null) + { entry.IsCrypted = true; - if (entry.Crc < 0) { + if (entry.Crc < 0) + { // Need to append a data descriptor as the crc isnt available for use // with encryption, the date is used instead. Setting the flag // indicates this to the decompressor. @@ -278,7 +303,8 @@ public void PutNextEntry(ZipEntry entry) curMethod = method; sizePatchPos = -1; - if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { + if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) + { entry.ForceZip64(); } @@ -291,30 +317,41 @@ public void PutNextEntry(ZipEntry entry) WriteLeInt((int)entry.DosTime); // TODO: Refactor header writing. Its done in several places. - if (headerInfoAvailable) { + if (headerInfoAvailable) + { WriteLeInt((int)entry.Crc); - if (entry.LocalHeaderRequiresZip64) { + if (entry.LocalHeaderRequiresZip64) + { WriteLeInt(-1); WriteLeInt(-1); - } else { + } + else + { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } - } else { - if (patchEntryHeader) { + } + else + { + if (patchEntryHeader) + { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); // Crc - if (patchEntryHeader) { + if (patchEntryHeader) + { sizePatchPos = baseOutputStream_.Position; } // For local header both sizes appear in Zip64 Extended Information - if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { + if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) + { WriteLeInt(-1); WriteLeInt(-1); - } else { + } + else + { WriteLeInt(0); // Compressed size WriteLeInt(0); // Uncompressed size } @@ -322,35 +359,45 @@ public void PutNextEntry(ZipEntry entry) byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name); - if (name.Length > 0xFFFF) { + if (name.Length > 0xFFFF) + { throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); - if (entry.LocalHeaderRequiresZip64) { + if (entry.LocalHeaderRequiresZip64) + { ed.StartNewEntry(); - if (headerInfoAvailable) { + if (headerInfoAvailable) + { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); - } else { + } + else + { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); - if (!ed.Find(1)) { + if (!ed.Find(1)) + { throw new ZipException("Internal error cant find extra data"); } - if (patchEntryHeader) { + if (patchEntryHeader) + { sizePatchPos = ed.CurrentReadIndex; } - } else { + } + else + { ed.Delete(1); } - if (entry.AESKeySize > 0) { + if (entry.AESKeySize > 0) + { AddExtraDataAES(entry, ed); } byte[] extra = ed.GetEntryData(); @@ -358,15 +405,18 @@ public void PutNextEntry(ZipEntry entry) WriteLeShort(name.Length); WriteLeShort(extra.Length); - if (name.Length > 0) { + if (name.Length > 0) + { baseOutputStream_.Write(name, 0, name.Length); } - if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { + if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) + { sizePatchPos += baseOutputStream_.Position; } - if (extra.Length > 0) { + if (extra.Length > 0) + { baseOutputStream_.Write(extra, 0, extra.Length); } @@ -378,19 +428,27 @@ public void PutNextEntry(ZipEntry entry) // Activate the entry. curEntry = entry; crc.Reset(); - if (method == CompressionMethod.Deflated) { + if (method == CompressionMethod.Deflated) + { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; - if (entry.IsCrypted) { - if (entry.AESKeySize > 0) { + if (entry.IsCrypted) + { + if (entry.AESKeySize > 0) + { WriteAESHeader(entry); - } else { - if (entry.Crc < 0) { // so testing Zip will says its ok + } + else + { + if (entry.Crc < 0) + { // so testing Zip will says its ok WriteEncryptionHeader(entry.DosTime << 16); - } else { + } + else + { WriteEncryptionHeader(entry.Crc); } } @@ -408,74 +466,96 @@ public void PutNextEntry(ZipEntry entry) /// public void CloseEntry() { - if (curEntry == null) { + if (curEntry == null) + { throw new InvalidOperationException("No open entry"); } long csize = size; // First finish the deflater, if appropriate - if (curMethod == CompressionMethod.Deflated) { - if (size >= 0) { + if (curMethod == CompressionMethod.Deflated) + { + if (size >= 0) + { base.Finish(); csize = deflater_.TotalOut; - } else { + } + else + { deflater_.Reset(); } } // Write the AES Authentication Code (a hash of the compressed and encrypted data) - if (curEntry.AESKeySize > 0) { + if (curEntry.AESKeySize > 0) + { baseOutputStream_.Write(AESAuthCode, 0, 10); } - if (curEntry.Size < 0) { + if (curEntry.Size < 0) + { curEntry.Size = size; - } else if (curEntry.Size != size) { + } + else if (curEntry.Size != size) + { throw new ZipException("size was " + size + ", but I expected " + curEntry.Size); } - if (curEntry.CompressedSize < 0) { + if (curEntry.CompressedSize < 0) + { curEntry.CompressedSize = csize; - } else if (curEntry.CompressedSize != csize) { + } + else if (curEntry.CompressedSize != csize) + { throw new ZipException("compressed size was " + csize + ", but I expected " + curEntry.CompressedSize); } - if (curEntry.Crc < 0) { + if (curEntry.Crc < 0) + { curEntry.Crc = crc.Value; - } else if (curEntry.Crc != crc.Value) { + } + else if (curEntry.Crc != crc.Value) + { throw new ZipException("crc was " + crc.Value + ", but I expected " + curEntry.Crc); } offset += csize; - if (curEntry.IsCrypted) { - if (curEntry.AESKeySize > 0) { + if (curEntry.IsCrypted) + { + if (curEntry.AESKeySize > 0) + { curEntry.CompressedSize += curEntry.AESOverheadSize; - - } else { + } + else + { curEntry.CompressedSize += ZipConstants.CryptoHeaderSize; } } // Patch the header if possible - if (patchEntryHeader) { + if (patchEntryHeader) + { patchEntryHeader = false; long curPos = baseOutputStream_.Position; baseOutputStream_.Seek(crcPatchPos, SeekOrigin.Begin); WriteLeInt((int)curEntry.Crc); - if (curEntry.LocalHeaderRequiresZip64) { - - if (sizePatchPos == -1) { + if (curEntry.LocalHeaderRequiresZip64) + { + if (sizePatchPos == -1) + { throw new ZipException("Entry requires zip64 but this has been turned off"); } baseOutputStream_.Seek(sizePatchPos, SeekOrigin.Begin); WriteLeLong(curEntry.Size); WriteLeLong(curEntry.CompressedSize); - } else { + } + else + { WriteLeInt((int)curEntry.CompressedSize); WriteLeInt((int)curEntry.Size); } @@ -483,15 +563,19 @@ public void CloseEntry() } // Add data descriptor if flagged as required - if ((curEntry.Flags & 8) != 0) { + if ((curEntry.Flags & 8) != 0) + { WriteLeInt(ZipConstants.DataDescriptorSignature); WriteLeInt(unchecked((int)curEntry.Crc)); - if (curEntry.LocalHeaderRequiresZip64) { + if (curEntry.LocalHeaderRequiresZip64) + { WriteLeLong(curEntry.CompressedSize); WriteLeLong(curEntry.Size); offset += ZipConstants.Zip64DataDescriptorSize; - } else { + } + else + { WriteLeInt((int)curEntry.CompressedSize); WriteLeInt((int)curEntry.Size); offset += ZipConstants.DataDescriptorSize; @@ -502,7 +586,7 @@ public void CloseEntry() curEntry = null; } - void WriteEncryptionHeader(long crcValue) + private void WriteEncryptionHeader(long crcValue) { offset += ZipConstants.CryptoHeaderSize; @@ -519,7 +603,6 @@ void WriteEncryptionHeader(long crcValue) private static void AddExtraDataAES(ZipEntry entry, ZipExtraData extraData) { - // Vendor Version: AE-1 IS 1. AE-2 is 2. With AE-2 no CRC is required and 0 is stored. const int VENDOR_VERSION = 2; // Vendor ID is the two ASCII characters "AE". @@ -566,49 +649,59 @@ private void WriteAESHeader(ZipEntry entry) /// No entry is active. public override void Write(byte[] buffer, int offset, int count) { - if (curEntry == null) { + if (curEntry == null) + { throw new InvalidOperationException("No open entry."); } - if (buffer == null) { + if (buffer == null) + { throw new ArgumentNullException(nameof(buffer)); } - if (offset < 0) { + if (offset < 0) + { throw new ArgumentOutOfRangeException(nameof(offset), "Cannot be negative"); } - if (count < 0) { + if (count < 0) + { throw new ArgumentOutOfRangeException(nameof(count), "Cannot be negative"); } - if ((buffer.Length - offset) < count) { + if ((buffer.Length - offset) < count) + { throw new ArgumentException("Invalid offset/count combination"); } crc.Update(new ArraySegment(buffer, offset, count)); size += count; - switch (curMethod) { + switch (curMethod) + { case CompressionMethod.Deflated: base.Write(buffer, offset, count); break; case CompressionMethod.Stored: - if (Password != null) { + if (Password != null) + { CopyAndEncrypt(buffer, offset, count); - } else { + } + else + { baseOutputStream_.Write(buffer, offset, count); } break; } } - void CopyAndEncrypt(byte[] buffer, int offset, int count) + private void CopyAndEncrypt(byte[] buffer, int offset, int count) { const int CopyBufferSize = 4096; byte[] localBuffer = new byte[CopyBufferSize]; - while (count > 0) { + while (count > 0) + { int bufferCount = (count < CopyBufferSize) ? count : CopyBufferSize; Array.Copy(buffer, offset, localBuffer, 0, bufferCount); @@ -635,18 +728,21 @@ void CopyAndEncrypt(byte[] buffer, int offset, int count) /// public override void Finish() { - if (entries == null) { + if (entries == null) + { return; } - if (curEntry != null) { + if (curEntry != null) + { CloseEntry(); } long numEntries = entries.Count; long sizeEntries = 0; - foreach (ZipEntry entry in entries) { + foreach (ZipEntry entry in entries) + { WriteLeInt(ZipConstants.CentralHeaderSignature); WriteLeShort(ZipConstants.VersionMadeBy); WriteLeShort(entry.Version); @@ -656,49 +752,63 @@ public override void Finish() WriteLeInt((int)entry.Crc); if (entry.IsZip64Forced() || - (entry.CompressedSize >= uint.MaxValue)) { + (entry.CompressedSize >= uint.MaxValue)) + { WriteLeInt(-1); - } else { + } + else + { WriteLeInt((int)entry.CompressedSize); } if (entry.IsZip64Forced() || - (entry.Size >= uint.MaxValue)) { + (entry.Size >= uint.MaxValue)) + { WriteLeInt(-1); - } else { + } + else + { WriteLeInt((int)entry.Size); } byte[] name = ZipStrings.ConvertToArray(entry.Flags, entry.Name); - if (name.Length > 0xffff) { + if (name.Length > 0xffff) + { throw new ZipException("Name too long."); } var ed = new ZipExtraData(entry.ExtraData); - if (entry.CentralHeaderRequiresZip64) { + if (entry.CentralHeaderRequiresZip64) + { ed.StartNewEntry(); if (entry.IsZip64Forced() || - (entry.Size >= 0xffffffff)) { + (entry.Size >= 0xffffffff)) + { ed.AddLeLong(entry.Size); } if (entry.IsZip64Forced() || - (entry.CompressedSize >= 0xffffffff)) { + (entry.CompressedSize >= 0xffffffff)) + { ed.AddLeLong(entry.CompressedSize); } - if (entry.Offset >= 0xffffffff) { + if (entry.Offset >= 0xffffffff) + { ed.AddLeLong(entry.Offset); } ed.AddNewEntry(1); - } else { + } + else + { ed.Delete(1); } - if (entry.AESKeySize > 0) { + if (entry.AESKeySize > 0) + { AddExtraDataAES(entry, ed); } byte[] extra = ed.GetEntryData(); @@ -708,7 +818,8 @@ public override void Finish() ZipStrings.ConvertToArray(entry.Flags, entry.Comment) : new byte[0]; - if (entryComment.Length > 0xffff) { + if (entryComment.Length > 0xffff) + { throw new ZipException("Comment too long."); } @@ -719,38 +830,51 @@ public override void Finish() WriteLeShort(0); // internal file attributes // external file attributes - if (entry.ExternalFileAttributes != -1) { + if (entry.ExternalFileAttributes != -1) + { WriteLeInt(entry.ExternalFileAttributes); - } else { - if (entry.IsDirectory) { // mark entry as directory (from nikolam.AT.perfectinfo.com) + } + else + { + if (entry.IsDirectory) + { // mark entry as directory (from nikolam.AT.perfectinfo.com) WriteLeInt(16); - } else { + } + else + { WriteLeInt(0); } } - if (entry.Offset >= uint.MaxValue) { + if (entry.Offset >= uint.MaxValue) + { WriteLeInt(-1); - } else { + } + else + { WriteLeInt((int)entry.Offset); } - if (name.Length > 0) { + if (name.Length > 0) + { baseOutputStream_.Write(name, 0, name.Length); } - if (extra.Length > 0) { + if (extra.Length > 0) + { baseOutputStream_.Write(extra, 0, extra.Length); } - if (entryComment.Length > 0) { + if (entryComment.Length > 0) + { baseOutputStream_.Write(entryComment, 0, entryComment.Length); } sizeEntries += ZipConstants.CentralHeaderBaseSize + name.Length + extra.Length + entryComment.Length; } - using (ZipHelperStream zhs = new ZipHelperStream(baseOutputStream_)) { + using (ZipHelperStream zhs = new ZipHelperStream(baseOutputStream_)) + { zhs.WriteEndOfCentralDirectory(numEntries, sizeEntries, offset, zipComment); } @@ -758,60 +882,62 @@ public override void Finish() } #region Instance Fields + /// /// The entries for the archive. /// - List entries = new List(); + private List entries = new List(); /// /// Used to track the crc of data added to entries. /// - Crc32 crc = new Crc32(); + private Crc32 crc = new Crc32(); /// /// The current entry being added. /// - ZipEntry curEntry; + private ZipEntry curEntry; - int defaultCompressionLevel = Deflater.DEFAULT_COMPRESSION; + private int defaultCompressionLevel = Deflater.DEFAULT_COMPRESSION; - CompressionMethod curMethod = CompressionMethod.Deflated; + private CompressionMethod curMethod = CompressionMethod.Deflated; /// /// Used to track the size of data for an entry during writing. /// - long size; + private long size; /// /// Offset to be recorded for each entry in the central header. /// - long offset; + private long offset; /// /// Comment for the entire archive recorded in central header. /// - byte[] zipComment = new byte[0]; + private byte[] zipComment = new byte[0]; /// /// Flag indicating that header patching is required for the current entry. /// - bool patchEntryHeader; + private bool patchEntryHeader; /// /// Position to patch crc /// - long crcPatchPos = -1; + private long crcPatchPos = -1; /// /// Position to patch size. /// - long sizePatchPos = -1; + private long sizePatchPos = -1; // Default is dynamic which is not backwards compatible and can cause problems // with XP's built in compression which cant read Zip64 archives. // However it does avoid the situation were a large file is added and cannot be completed correctly. // NOTE: Setting the size for entries before they are added is the best solution! - UseZip64 useZip64_ = UseZip64.Dynamic; - #endregion + private UseZip64 useZip64_ = UseZip64.Dynamic; + + #endregion Instance Fields } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs index e38ef7f0c..0950233d0 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs @@ -8,7 +8,6 @@ namespace ICSharpCode.SharpZipLib.Zip /// public static class ZipStrings { - static ZipStrings() { try @@ -24,14 +23,13 @@ static ZipStrings() /// Code page backing field /// - /// The original Zip specification (https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) states - /// that file names should only be encoded with IBM Code Page 437 or UTF-8. - /// In practice, most zip apps use OEM or system encoding (typically cp437 on Windows). + /// The original Zip specification (https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) states + /// that file names should only be encoded with IBM Code Page 437 or UTF-8. + /// In practice, most zip apps use OEM or system encoding (typically cp437 on Windows). /// Let's be good citizens and default to UTF-8 http://utf8everywhere.org/ /// private static int codePage = Encoding.UTF8.CodePage; - /// /// Encoding used for string conversion. Setting this to 65001 (UTF-8) will /// also set the Language encoding flag to indicate UTF-8 encoded file names. @@ -54,7 +52,6 @@ public static int CodePage } } - private const int FallbackCodePage = 437; /// @@ -95,7 +92,7 @@ public static bool UseUnicode /// /// Convert a portion of a byte array to a string using - /// + /// /// /// Data to convert to string /// @@ -105,7 +102,7 @@ public static bool UseUnicode /// /// data[0]..data[count - 1] converted to a string /// - public static string ConvertToString(byte[] data, int count) + public static string ConvertToString(byte[] data, int count) => data == null ? string.Empty : Encoding.GetEncoding(CodePage).GetString(data, 0, count); diff --git a/test/ICSharpCode.SharpZipLib.TestBootstrapper/Program.cs b/test/ICSharpCode.SharpZipLib.TestBootstrapper/Program.cs index aa36286b8..4a030de1f 100644 --- a/test/ICSharpCode.SharpZipLib.TestBootstrapper/Program.cs +++ b/test/ICSharpCode.SharpZipLib.TestBootstrapper/Program.cs @@ -1,17 +1,14 @@ -using System; -using NUnit.Common; -using NUnitLite; +using NUnitLite; using System.Reflection; namespace ICSharpCode.SharpZipLib.TestBootstrapper { public class Program - { - static void Main(string[] args) + { + private static void Main(string[] args) { new AutoRun(typeof(Tests.Base.InflaterDeflaterTestSuite).GetTypeInfo().Assembly) .Execute(args); } - - } + } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs b/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs index 6bfc07c8f..201622ab3 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/BZip2/Bzip2Tests.cs @@ -1,10 +1,8 @@ -using System; -using System.IO; using ICSharpCode.SharpZipLib.BZip2; using ICSharpCode.SharpZipLib.Tests.TestSupport; using NUnit.Framework; -using System.Threading; -using System.Diagnostics; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.BZip2 { @@ -33,18 +31,22 @@ public void BasicRoundTrip() ms = new MemoryStream(ms.GetBuffer()); ms.Seek(0, SeekOrigin.Begin); - using (BZip2InputStream inStream = new BZip2InputStream(ms)) { + using (BZip2InputStream inStream = new BZip2InputStream(ms)) + { byte[] buf2 = new byte[buf.Length]; int pos = 0; - while (true) { + while (true) + { int numRead = inStream.Read(buf2, pos, 4096); - if (numRead <= 0) { + if (numRead <= 0) + { break; } pos += numRead; } - for (int i = 0; i < buf.Length; ++i) { + for (int i = 0; i < buf.Length; ++i) + { Assert.AreEqual(buf2[i], buf[i]); } } @@ -64,12 +66,15 @@ public void CreateEmptyArchive() ms.Seek(0, SeekOrigin.Begin); - using (BZip2InputStream inStream = new BZip2InputStream(ms)) { + using (BZip2InputStream inStream = new BZip2InputStream(ms)) + { byte[] buffer = new byte[1024]; int pos = 0; - while (true) { + while (true) + { int numRead = inStream.Read(buffer, 0, buffer.Length); - if (numRead <= 0) { + if (numRead <= 0) + { break; } pos += numRead; @@ -79,11 +84,11 @@ public void CreateEmptyArchive() } } - BZip2OutputStream outStream_; - BZip2InputStream inStream_; - WindowedStream window_; - long readTarget_; - long writeTarget_; + private BZip2OutputStream outStream_; + private BZip2InputStream inStream_; + private WindowedStream window_; + private long readTarget_; + private long writeTarget_; [Test] [Category("BZip2")] @@ -109,7 +114,5 @@ public void ReadWriteThroughput() output: w => new BZip2OutputStream(w) ); } - - } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs index 9dd7679b9..1d736558e 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Base/InflaterDeflaterTests.cs @@ -1,11 +1,11 @@ -using System; -using System.IO; -using System.Security; -using System.Text; using ICSharpCode.SharpZipLib.Tests.TestSupport; using ICSharpCode.SharpZipLib.Zip.Compression; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using NUnit.Framework; +using System; +using System.IO; +using System.Security; +using System.Text; namespace ICSharpCode.SharpZipLib.Tests.Base { @@ -15,7 +15,7 @@ namespace ICSharpCode.SharpZipLib.Tests.Base [TestFixture] public class InflaterDeflaterTestSuite { - void Inflate(MemoryStream ms, byte[] original, int level, bool zlib) + private void Inflate(MemoryStream ms, byte[] original, int level, bool zlib) { ms.Seek(0, SeekOrigin.Begin); @@ -26,48 +26,61 @@ void Inflate(MemoryStream ms, byte[] original, int level, bool zlib) int currentIndex = 0; int count = buf2.Length; - try { - while (true) { + try + { + while (true) + { int numRead = inStream.Read(buf2, currentIndex, count); - if (numRead <= 0) { + if (numRead <= 0) + { break; } currentIndex += numRead; count -= numRead; } - } catch (Exception ex) { + } + catch (Exception ex) + { Console.WriteLine("Unexpected exception - '{0}'", ex.Message); throw; } - if (currentIndex != original.Length) { + if (currentIndex != original.Length) + { Console.WriteLine("Original {0}, new {1}", original.Length, currentIndex); Assert.Fail("Lengths different"); } - for (int i = 0; i < original.Length; ++i) { - if (buf2[i] != original[i]) { + for (int i = 0; i < original.Length; ++i) + { + if (buf2[i] != original[i]) + { string description = string.Format("Difference at {0} level {1} zlib {2} ", i, level, zlib); - if (original.Length < 2048) { + if (original.Length < 2048) + { var builder = new StringBuilder(description); - for (int d = 0; d < original.Length; ++d) { + for (int d = 0; d < original.Length; ++d) + { builder.AppendFormat("{0} ", original[d]); } Assert.Fail(builder.ToString()); - } else { + } + else + { Assert.Fail(description); } } } } - MemoryStream Deflate(byte[] data, int level, bool zlib) + private MemoryStream Deflate(byte[] data, int level, bool zlib) { var memoryStream = new MemoryStream(); var deflater = new Deflater(level, !zlib); - using (DeflaterOutputStream outStream = new DeflaterOutputStream(memoryStream, deflater)) { + using (DeflaterOutputStream outStream = new DeflaterOutputStream(memoryStream, deflater)) + { outStream.IsStreamOwner = false; outStream.Write(data, 0, data.Length); outStream.Flush(); @@ -76,7 +89,7 @@ MemoryStream Deflate(byte[] data, int level, bool zlib) return memoryStream; } - void RandomDeflateInflate(int size, int level, bool zlib) + private void RandomDeflateInflate(int size, int level, bool zlib) { byte[] buffer = new byte[size]; var rnd = new Random(); @@ -93,33 +106,38 @@ void RandomDeflateInflate(int size, int level, bool zlib) [Category("Base")] public void InflateDeflateZlib() { - for (int level = 0; level < 10; ++level) { + for (int level = 0; level < 10; ++level) + { RandomDeflateInflate(100000, level, true); } } - delegate void RunCompress(byte[] buffer); + private delegate void RunCompress(byte[] buffer); - int runLevel; - bool runZlib; - long runCount; - Random runRandom = new Random(5); + private int runLevel; + private bool runZlib; + private long runCount; + private Random runRandom = new Random(5); - void DeflateAndInflate(byte[] buffer) + private void DeflateAndInflate(byte[] buffer) { ++runCount; MemoryStream ms = Deflate(buffer, runLevel, runZlib); Inflate(ms, buffer, runLevel, runZlib); } - void TryVariants(RunCompress test, byte[] buffer, int index) + private void TryVariants(RunCompress test, byte[] buffer, int index) { int worker = 0; - while (worker <= 255) { + while (worker <= 255) + { buffer[index] = (byte)worker; - if (index < buffer.Length - 1) { + if (index < buffer.Length - 1) + { TryVariants(test, buffer, index + 1); - } else { + } + else + { test(buffer); } @@ -127,7 +145,7 @@ void TryVariants(RunCompress test, byte[] buffer, int index) } } - void TryManyVariants(int level, bool zlib, RunCompress test, byte[] buffer) + private void TryManyVariants(int level, bool zlib, RunCompress test, byte[] buffer) { runLevel = level; runZlib = zlib; @@ -151,7 +169,8 @@ void TryManyVariants(int level, bool zlib, RunCompress test, byte[] buffer) [Category("Base")] public void InflateDeflateNonZlib() { - for (int level = 0; level < 10; ++level) { + for (int level = 0; level < 10; ++level) + { RandomDeflateInflate(100000, level, false); } } @@ -161,9 +180,12 @@ public void InflateDeflateNonZlib() public void CloseDeflatorWithNestedUsing() { string tempFile = null; - try { + try + { tempFile = Path.GetTempPath(); - } catch (SecurityException) { + } + catch (SecurityException) + { } Assert.IsNotNull(tempFile, "No permission to execute this test?"); @@ -171,7 +193,8 @@ public void CloseDeflatorWithNestedUsing() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); using (FileStream diskFile = File.Create(tempFile)) using (DeflaterOutputStream deflator = new DeflaterOutputStream(diskFile)) - using (StreamWriter txtFile = new StreamWriter(deflator)) { + using (StreamWriter txtFile = new StreamWriter(deflator)) + { txtFile.Write("Hello"); txtFile.Flush(); } @@ -205,7 +228,6 @@ public void DeflatorStreamOwnership() Assert.IsFalse(memStream.IsClosed, "Should not be closed after parent owner close"); Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close"); - } [Test] @@ -234,7 +256,6 @@ public void InflatorStreamOwnership() Assert.IsFalse(memStream.IsClosed, "Should not be closed after parent owner close"); Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close"); - } [Test] @@ -242,9 +263,12 @@ public void InflatorStreamOwnership() public void CloseInflatorWithNestedUsing() { string tempFile = null; - try { + try + { tempFile = Path.GetTempPath(); - } catch (SecurityException) { + } + catch (SecurityException) + { } Assert.IsNotNull(tempFile, "No permission to execute this test?"); @@ -252,14 +276,16 @@ public void CloseInflatorWithNestedUsing() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); using (FileStream diskFile = File.Create(tempFile)) using (DeflaterOutputStream deflator = new DeflaterOutputStream(diskFile)) - using (StreamWriter textWriter = new StreamWriter(deflator)) { + using (StreamWriter textWriter = new StreamWriter(deflator)) + { textWriter.Write("Hello"); textWriter.Flush(); } using (FileStream diskFile = File.OpenRead(tempFile)) using (InflaterInputStream deflator = new InflaterInputStream(diskFile)) - using (StreamReader textReader = new StreamReader(deflator)) { + using (StreamReader textReader = new StreamReader(deflator)) + { char[] buffer = new char[5]; int readCount = textReader.Read(buffer, 0, 5); Assert.AreEqual(5, readCount); @@ -267,7 +293,6 @@ public void CloseInflatorWithNestedUsing() var b = new StringBuilder(); b.Append(buffer); Assert.AreEqual("Hello", b.ToString()); - } File.Delete(tempFile); diff --git a/test/ICSharpCode.SharpZipLib.Tests/Checksum/ChecksumTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Checksum/ChecksumTests.cs index 002dc1dcc..4ad315c1e 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Checksum/ChecksumTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Checksum/ChecksumTests.cs @@ -1,5 +1,5 @@ -using NUnit.Framework; -using ICSharpCode.SharpZipLib.Checksum; +using ICSharpCode.SharpZipLib.Checksum; +using NUnit.Framework; using System; namespace ICSharpCode.SharpZipLib.Tests.Checksum @@ -8,7 +8,7 @@ namespace ICSharpCode.SharpZipLib.Tests.Checksum [Category("Checksum")] public class ChecksumTests { - readonly + private readonly // Represents ASCII string of "123456789" byte[] check = { 49, 50, 51, 52, 53, 54, 55, 56, 57 }; @@ -59,57 +59,74 @@ public void CRC_32() private void exceptionTesting(IChecksum crcUnderTest) { - bool exception = false; - try { + try + { crcUnderTest.Update(null); - } catch (ArgumentNullException) { + } + catch (ArgumentNullException) + { exception = true; } Assert.IsTrue(exception, "Passing a null buffer should cause an ArgumentNullException"); // reset exception exception = false; - try { + try + { crcUnderTest.Update(new ArraySegment(null, 0, 0)); - } catch (ArgumentNullException) { + } + catch (ArgumentNullException) + { exception = true; } Assert.IsTrue(exception, "Passing a null buffer should cause an ArgumentNullException"); // reset exception exception = false; - try { + try + { crcUnderTest.Update(new ArraySegment(check, -1, 9)); - } catch (ArgumentOutOfRangeException) { + } + catch (ArgumentOutOfRangeException) + { exception = true; } Assert.IsTrue(exception, "Passing a negative offset should cause an ArgumentOutOfRangeException"); // reset exception exception = false; - try { + try + { crcUnderTest.Update(new ArraySegment(check, 10, 0)); - } catch (ArgumentException) { + } + catch (ArgumentException) + { exception = true; } Assert.IsTrue(exception, "Passing an offset greater than buffer.Length should cause an ArgumentException"); // reset exception exception = false; - try { + try + { crcUnderTest.Update(new ArraySegment(check, 0, -1)); - } catch (ArgumentOutOfRangeException) { + } + catch (ArgumentOutOfRangeException) + { exception = true; } Assert.IsTrue(exception, "Passing a negative count should cause an ArgumentOutOfRangeException"); // reset exception exception = false; - try { + try + { crcUnderTest.Update(new ArraySegment(check, 0, 10)); - } catch (ArgumentException) { + } + catch (ArgumentException) + { exception = true; } Assert.IsTrue(exception, "Passing a count + offset greater than buffer.Length should cause an ArgumentException"); diff --git a/test/ICSharpCode.SharpZipLib.Tests/Core/CoreTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Core/CoreTests.cs index 4d49862c5..985718fb2 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Core/CoreTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Core/CoreTests.cs @@ -15,19 +15,22 @@ public void FilterQuoting() filters = NameFilter.SplitQuoted(";;;"); Assert.AreEqual(4, filters.Length); - foreach (string filter in filters) { + foreach (string filter in filters) + { Assert.AreEqual("", filter); } filters = NameFilter.SplitQuoted("a;a;a;a;a"); Assert.AreEqual(5, filters.Length); - foreach (string filter in filters) { + foreach (string filter in filters) + { Assert.AreEqual("a", filter); } filters = NameFilter.SplitQuoted(@"a\;;a\;;a\;;a\;;a\;"); Assert.AreEqual(5, filters.Length); - foreach (string filter in filters) { + foreach (string filter in filters) + { Assert.AreEqual("a;", filter); } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs b/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs index 941101d94..1dbe7f9e9 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/GZip/GZipTests.cs @@ -1,10 +1,8 @@ -using System; -using System.IO; using ICSharpCode.SharpZipLib.GZip; using ICSharpCode.SharpZipLib.Tests.TestSupport; using NUnit.Framework; -using System.Threading; -using System.Diagnostics; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.GZip { @@ -39,9 +37,11 @@ public void TestGZip() int currentIndex = 0; int count = buf2.Length; - while (true) { + while (true) + { int numRead = inStream.Read(buf2, currentIndex, count); - if (numRead <= 0) { + if (numRead <= 0) + { break; } currentIndex += numRead; @@ -50,7 +50,8 @@ public void TestGZip() Assert.AreEqual(0, count); - for (int i = 0; i < buf.Length; ++i) { + for (int i = 0; i < buf.Length; ++i) + { Assert.AreEqual(buf2[i], buf[i]); } } @@ -65,7 +66,8 @@ public void DelayedHeaderWriteNoData() var ms = new MemoryStream(); Assert.AreEqual(0, ms.Length); - using (GZipOutputStream outStream = new GZipOutputStream(ms)) { + using (GZipOutputStream outStream = new GZipOutputStream(ms)) + { Assert.AreEqual(0, ms.Length); } @@ -83,7 +85,8 @@ public void DelayedHeaderWriteWithData() { var ms = new MemoryStream(); Assert.AreEqual(0, ms.Length); - using (GZipOutputStream outStream = new GZipOutputStream(ms)) { + using (GZipOutputStream outStream = new GZipOutputStream(ms)) + { Assert.AreEqual(0, ms.Length); outStream.WriteByte(45); @@ -170,7 +173,6 @@ public void InputStreamOwnership() Assert.IsFalse(memStream.IsClosed, "Should not be closed after parent owner close"); Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close"); - } [Test] @@ -194,7 +196,8 @@ public void DoubleClose() s.Close(); memStream = new TrackedMemoryStream(); - using (GZipOutputStream no2 = new GZipOutputStream(memStream)) { + using (GZipOutputStream no2 = new GZipOutputStream(memStream)) + { s.Close(); } } @@ -206,10 +209,13 @@ public void WriteAfterFinish() var s = new GZipOutputStream(memStream); s.Finish(); - try { + try + { s.WriteByte(7); Assert.Fail("Write should fail"); - } catch { + } + catch + { } } @@ -220,64 +226,68 @@ public void WriteAfterClose() var s = new GZipOutputStream(memStream); s.Close(); - try { + try + { s.WriteByte(7); Assert.Fail("Write should fail"); - } catch { + } + catch + { } } - /// - /// Verify that if a decompression was successful for at least one block we're exiting gracefully. - /// - [Test] - public void TrailingGarbage() - { - /* ARRANGE */ + /// + /// Verify that if a decompression was successful for at least one block we're exiting gracefully. + /// + [Test] + public void TrailingGarbage() + { + /* ARRANGE */ var ms = new MemoryStream(); var outStream = new GZipOutputStream(ms); - // input buffer to be compressed + // input buffer to be compressed byte[] buf = new byte[100000]; var rnd = new Random(); rnd.NextBytes(buf); - // compress input buffer + // compress input buffer outStream.Write(buf, 0, buf.Length); outStream.Flush(); outStream.Finish(); - // generate random trailing garbage and add to the compressed stream - byte[] garbage = new byte[4096]; - rnd.NextBytes(garbage); - ms.Write(garbage, 0, garbage.Length); + // generate random trailing garbage and add to the compressed stream + byte[] garbage = new byte[4096]; + rnd.NextBytes(garbage); + ms.Write(garbage, 0, garbage.Length); - // rewind the concatenated stream + // rewind the concatenated stream ms.Seek(0, SeekOrigin.Begin); - - /* ACT */ - // decompress concatenated stream + /* ACT */ + // decompress concatenated stream var inStream = new GZipInputStream(ms); byte[] buf2 = new byte[buf.Length]; int currentIndex = 0; int count = buf2.Length; - while (true) { - int numRead = inStream.Read(buf2, currentIndex, count); - if (numRead <= 0) { - break; - } - currentIndex += numRead; - count -= numRead; - } - + while (true) + { + int numRead = inStream.Read(buf2, currentIndex, count); + if (numRead <= 0) + { + break; + } + currentIndex += numRead; + count -= numRead; + } - /* ASSERT */ + /* ASSERT */ Assert.AreEqual(0, count); - for (int i = 0; i < buf.Length; ++i) { + for (int i = 0; i < buf.Length; ++i) + { Assert.AreEqual(buf2[i], buf[i]); } - } + } [Test] [Category("GZip")] @@ -290,7 +300,6 @@ public void WriteThroughput() size: TestDataSize.Large, output: w => new GZipOutputStream(w) ); - } [Test] @@ -304,9 +313,6 @@ public void ReadWriteThroughput() input: w => new GZipInputStream(w), output: w => new GZipOutputStream(w) ); - } - - } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Lzw/LzwTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Lzw/LzwTests.cs index f72521d45..eef5e4898 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Lzw/LzwTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Lzw/LzwTests.cs @@ -1,11 +1,10 @@ -using System.IO; -using ICSharpCode.SharpZipLib.Lzw; +using ICSharpCode.SharpZipLib.Lzw; using ICSharpCode.SharpZipLib.Tests.TestSupport; using NUnit.Framework; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.Lzw { - [TestFixture] public class LzwTestSuite { @@ -44,16 +43,18 @@ public void ZeroLengthInputStream() { var lis = new LzwInputStream(new MemoryStream()); bool exception = false; - try { + try + { lis.ReadByte(); - } catch { + } + catch + { exception = true; } Assert.IsTrue(exception, "reading from an empty stream should cause an exception"); } - [Test] [Category("LZW")] public void InputStreamOwnership() @@ -80,7 +81,6 @@ public void InputStreamOwnership() Assert.IsFalse(memStream.IsClosed, "Should not be closed after parent owner close"); Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close"); - } } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs index 0bcac4d54..33f9ae4df 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs @@ -1,21 +1,20 @@ -using System; -using System.IO; using ICSharpCode.SharpZipLib.Tar; using ICSharpCode.SharpZipLib.Tests.TestSupport; using NUnit.Framework; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.Tar { - /// /// This class contains test cases for Tar archive handling. /// [TestFixture] public class TarTestSuite { - int entryCount; + private int entryCount; - void EntryCounter(TarArchive archive, TarEntry entry, string message) + private void EntryCounter(TarArchive archive, TarEntry entry, string message) { entryCount++; } @@ -29,7 +28,8 @@ public void EmptyTar() { var ms = new MemoryStream(); int recordSize = 0; - using (TarArchive tarOut = TarArchive.CreateOutputTarArchive(ms)) { + using (TarArchive tarOut = TarArchive.CreateOutputTarArchive(ms)) + { recordSize = tarOut.RecordSize; } @@ -40,7 +40,8 @@ public void EmptyTar() ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms2.Seek(0, SeekOrigin.Begin); - using (TarArchive tarIn = TarArchive.CreateInputTarArchive(ms2)) { + using (TarArchive tarIn = TarArchive.CreateInputTarArchive(ms2)) + { entryCount = 0; tarIn.ProgressMessageEvent += EntryCounter; tarIn.ListContents(); @@ -59,10 +60,12 @@ public void BlockFactorHandling() const int MaximumBlockFactor = 64; const int FillFactor = 2; - for (int factor = MinimumBlockFactor; factor < MaximumBlockFactor; ++factor) { + for (int factor = MinimumBlockFactor; factor < MaximumBlockFactor; ++factor) + { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms, factor)) { + using (TarOutputStream tarOut = new TarOutputStream(ms, factor)) + { TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); entry.Size = (TarBuffer.BlockSize * factor * FillFactor); tarOut.PutNextEntry(entry); @@ -73,7 +76,8 @@ public void BlockFactorHandling() r.NextBytes(buffer); // Last block is a partial one - for (int i = 0; i < factor * FillFactor; ++i) { + for (int i = 0; i < factor * FillFactor; ++i) + { tarOut.Write(buffer, 0, buffer.Length); } } @@ -90,10 +94,12 @@ public void BlockFactorHandling() Assert.AreEqual(TarBuffer.BlockSize * totalBlocks, tarData.Length, "Tar file should contain {0} blocks in length", totalBlocks); - if (usedBlocks < totalBlocks) { + if (usedBlocks < totalBlocks) + { // Start at first byte after header. int byteIndex = TarBuffer.BlockSize * ((factor * FillFactor) + 1); - while (byteIndex < tarData.Length) { + while (byteIndex < tarData.Length) + { int blockNumber = byteIndex / TarBuffer.BlockSize; int offset = blockNumber % TarBuffer.BlockSize; Assert.AreEqual(0, tarData[byteIndex], @@ -115,12 +121,15 @@ public void TrailerContainsNulls() { const int TestBlockFactor = 3; - for (int iteration = 0; iteration < TestBlockFactor * 2; ++iteration) { + for (int iteration = 0; iteration < TestBlockFactor * 2; ++iteration) + { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms, TestBlockFactor)) { + using (TarOutputStream tarOut = new TarOutputStream(ms, TestBlockFactor)) + { TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); - if (iteration > 0) { + if (iteration > 0) + { entry.Size = (TarBuffer.BlockSize * (iteration - 1)) + 9; } tarOut.PutNextEntry(entry); @@ -130,13 +139,16 @@ public void TrailerContainsNulls() var r = new Random(); r.NextBytes(buffer); - if (iteration > 0) { - for (int i = 0; i < iteration - 1; ++i) { + if (iteration > 0) + { + for (int i = 0; i < iteration - 1; ++i) + { tarOut.Write(buffer, 0, buffer.Length); } // Last block is a partial one - for (int i = 1; i < 10; ++i) { + for (int i = 1; i < 10; ++i) + { tarOut.WriteByte((byte)i); } } @@ -154,10 +166,12 @@ public void TrailerContainsNulls() Assert.AreEqual(TarBuffer.BlockSize * totalBlocks, tarData.Length, string.Format("Tar file should be {0} blocks in length", totalBlocks)); - if (usedBlocks < totalBlocks) { + if (usedBlocks < totalBlocks) + { // Start at first byte after header. int byteIndex = TarBuffer.BlockSize * (iteration + 1); - while (byteIndex < tarData.Length) { + while (byteIndex < tarData.Length) + { int blockNumber = byteIndex / TarBuffer.BlockSize; int offset = blockNumber % TarBuffer.BlockSize; Assert.AreEqual(0, tarData[byteIndex], @@ -170,10 +184,11 @@ public void TrailerContainsNulls() } } - void TryLongName(string name) + private void TryLongName(string name) { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms)) { + using (TarOutputStream tarOut = new TarOutputStream(ms)) + { DateTime modTime = DateTime.Now; TarEntry entry = TarEntry.CreateTarEntry(name); @@ -184,7 +199,8 @@ void TryLongName(string name) ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms2.Seek(0, SeekOrigin.Begin); - using (TarInputStream tarIn = new TarInputStream(ms2)) { + using (TarInputStream tarIn = new TarInputStream(ms2)) + { TarEntry nextEntry = tarIn.GetNextEntry(); Assert.AreEqual(nextEntry.Name, name, "Name match failure"); @@ -224,7 +240,8 @@ public void LongNames() "11111111112222222222333333333344444444445555555555" + "66666666667777777777888888888899999999990000000000"); - for (int n = 1; n < 1024; ++n) { + for (int n = 1; n < 1024; ++n) + { string format = "{0," + n + "}"; string formatted = string.Format(format, "A"); TryLongName(formatted); @@ -279,10 +296,8 @@ public void ExtendedHeaderLongName() Assert.AreEqual(expectedName, entry.Name, "Entry name does not match expected value"); } - } - /// /// Test equals function for tar headers. /// @@ -355,7 +370,6 @@ public void HeaderEquality() h2.GroupName = h1.GroupName; Assert.IsTrue(h1.Equals(h2)); - h1.DevMajor = 165; Assert.IsFalse(h1.Equals(h2)); h2.DevMajor = h1.DevMajor; @@ -365,7 +379,6 @@ public void HeaderEquality() Assert.IsFalse(h1.Equals(h2)); h2.DevMinor = h1.DevMinor; Assert.IsTrue(h1.Equals(h2)); - } [Test] @@ -373,7 +386,8 @@ public void HeaderEquality() public void Checksum() { var ms = new MemoryStream(); - using (TarOutputStream tarOut = new TarOutputStream(ms)) { + using (TarOutputStream tarOut = new TarOutputStream(ms)) + { DateTime modTime = DateTime.Now; TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); @@ -387,7 +401,8 @@ public void Checksum() ms2.Seek(0, SeekOrigin.Begin); TarEntry nextEntry; - using (TarInputStream tarIn = new TarInputStream(ms2)) { + using (TarInputStream tarIn = new TarInputStream(ms2)) + { nextEntry = tarIn.GetNextEntry(); Assert.IsTrue(nextEntry.TarHeader.IsChecksumValid, "Checksum should be valid"); } @@ -398,12 +413,16 @@ public void Checksum() ms3.Write(new byte[] { 34 }, 0, 1); ms3.Seek(0, SeekOrigin.Begin); - using (TarInputStream tarIn = new TarInputStream(ms3)) { + using (TarInputStream tarIn = new TarInputStream(ms3)) + { bool trapped = false; - try { + try + { nextEntry = tarIn.GetNextEntry(); - } catch (TarException) { + } + catch (TarException) + { trapped = true; } @@ -422,7 +441,8 @@ public void ValuesPreserved() TarEntry entry; DateTime modTime = DateTime.Now; - using (TarOutputStream tarOut = new TarOutputStream(ms)) { + using (TarOutputStream tarOut = new TarOutputStream(ms)) + { entry = TarEntry.CreateTarEntry("TestEntry"); entry.GroupId = 12; entry.UserId = 14; @@ -438,20 +458,22 @@ public void ValuesPreserved() ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms2.Seek(0, SeekOrigin.Begin); - using (TarInputStream tarIn = new TarInputStream(ms2)) { + using (TarInputStream tarIn = new TarInputStream(ms2)) + { TarEntry nextEntry = tarIn.GetNextEntry(); Assert.AreEqual(entry.TarHeader.Checksum, nextEntry.TarHeader.Checksum, "Checksum"); Assert.IsTrue(nextEntry.Equals(entry), "Entries should be equal"); Assert.IsTrue(nextEntry.TarHeader.Equals(entry.TarHeader), "Headers should match"); - // Tar only stores seconds + // Tar only stores seconds var truncatedTime = new DateTime(modTime.Year, modTime.Month, modTime.Day, modTime.Hour, modTime.Minute, modTime.Second); Assert.AreEqual(truncatedTime, nextEntry.ModTime, "Modtimes should match"); entryCount = 0; - while (nextEntry != null) { + while (nextEntry != null) + { ++entryCount; nextEntry = tarIn.GetNextEntry(); } diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/PerformanceTesting.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/PerformanceTesting.cs index 15aad9055..73e581ef2 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/PerformanceTesting.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/PerformanceTesting.cs @@ -1,16 +1,14 @@ using NUnit.Framework; using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.ExceptionServices; -using System.Text; using System.Threading; namespace ICSharpCode.SharpZipLib.Tests.TestSupport { - internal static class PerformanceTesting - { + internal static class PerformanceTesting + { private const double ByteToMB = 1000000; private const int PacifierOffset = 0x100000; @@ -42,8 +40,6 @@ public static void TestReadWrite(int size, Func input, Func { var state = (PerfWorkerState)stateObject; @@ -57,7 +53,6 @@ public static void TestReadWrite(int size, Func input, Func input, Func output, Action /// Create a new RingBuffer with a specified size. /// /// The size of the ring buffer to create. public ReadWriteRingBuffer(int size, CancellationToken? token = null) { - if (size <= 0) { + if (size <= 0) + { throw new ArgumentOutOfRangeException(nameof(size)); } @@ -38,7 +39,8 @@ public ReadWriteRingBuffer(int size, CancellationToken? token = null) notFullEvent_ = new ManualResetEvent(true); #endif } - #endregion + + #endregion Constructors /// /// Clear the buffer contents. @@ -75,12 +77,14 @@ public void Close() /// The value to add. public void WriteByte(byte value) { - if (isClosed_) { + if (isClosed_) + { throw new ApplicationException("Buffer is closed"); } #if SimpleSynch - while (IsFull) { + while (IsFull) + { Thread.Sleep(waitSpan_); token_?.ThrowIfCancellationRequested(); } @@ -88,7 +92,8 @@ public void WriteByte(byte value) notFullEvent_.WaitOne(); #endif - lock (lockObject_) { + lock (lockObject_) + { array_[head_] = value; head_ = (head_ + 1) % array_.Length; @@ -116,13 +121,16 @@ public void WriteByte(byte value) public void Write(byte[] buffer, int index, int count) { - if (isClosed_) { + if (isClosed_) + { throw new ApplicationException("Buffer is closed"); } - while (count > 0) { + while (count > 0) + { #if SimpleSynch - while (IsFull) { + while (IsFull) + { Thread.Sleep(waitSpan_); token_?.ThrowIfCancellationRequested(); } @@ -132,17 +140,20 @@ public void Write(byte[] buffer, int index, int count) // Gauranteed to not be full at this point, however readers may sill read // from the buffer first. - lock (lockObject_) { + lock (lockObject_) + { int bytesToWrite = Length - Count; - if (count < bytesToWrite) { + if (count < bytesToWrite) + { bytesToWrite = count; } #if !SimpleSynch bool setEmpty = (count_ == 0); #endif - while (bytesToWrite > 0) { + while (bytesToWrite > 0) + { array_[head_] = buffer[index]; index++; @@ -178,7 +189,8 @@ public int ReadByte() int result = -1; #if SimpleSynch - while (!isClosed_ && IsEmpty) { + while (!isClosed_ && IsEmpty) + { Thread.Sleep(waitSpan_); token_?.ThrowIfCancellationRequested(); } @@ -186,8 +198,10 @@ public int ReadByte() notEmptyEvent_.WaitOne(); #endif - if (!IsEmpty) { - lock (lockObject_) { + if (!IsEmpty) + { + lock (lockObject_) + { result = array_[tail_]; tail_ = (tail_ + 1) % array_.Length; #if !SimpleSynch @@ -217,9 +231,11 @@ public int Read(byte[] buffer, int index, int count) { int result = 0; - while (count > 0) { + while (count > 0) + { #if SimpleSynch - while (!isClosed_ && IsEmpty) { + while (!isClosed_ && IsEmpty) + { Thread.Sleep(waitSpan_); token_?.ThrowIfCancellationRequested(); } @@ -227,13 +243,18 @@ public int Read(byte[] buffer, int index, int count) notEmptyEvent_.WaitOne(); #endif - if (IsEmpty) { + if (IsEmpty) + { count = 0; - } else { - lock (lockObject_) { + } + else + { + lock (lockObject_) + { int toRead = Count; - if (toRead > count) { + if (toRead > count) + { toRead = count; } @@ -243,7 +264,8 @@ public int Read(byte[] buffer, int index, int count) bool setFull = IsFull; #endif - while (toRead > 0) { + while (toRead > 0) + { buffer[index] = array_[tail_]; index++; @@ -276,48 +298,59 @@ public int Read(byte[] buffer, int index, int count) /// /// Gets a value indicating wether the buffer is empty or not. /// - public bool IsEmpty { + public bool IsEmpty + { get { return count_ == 0; } } - public bool IsFull { - get { + public bool IsFull + { + get + { return (count_ == array_.Length); } } - public bool IsClosed { + public bool IsClosed + { get { return isClosed_; } } /// /// Gets the number of elements in the buffer. /// - public int Count { - get { + public int Count + { + get + { return count_; } } - - public int Length { + public int Length + { get { return array_.Length; } } - public long BytesWritten { + public long BytesWritten + { get { return bytesWritten_; } } - public long BytesRead { + public long BytesRead + { get { return bytesRead_; } } /// /// Indexer - Get an element from the tail of the RingBuffer. /// - public byte this[int index] { - get { - if ((index < 0) || (index >= array_.Length)) { + public byte this[int index] + { + get + { + if ((index < 0) || (index >= array_.Length)) + { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -325,48 +358,50 @@ public byte this[int index] { } } - #endregion + #endregion Properties #region Instance Variables + /// /// Flag indicating the buffer is closed. /// - bool isClosed_; + private bool isClosed_; /// /// Index for the head of the buffer. /// /// Its the index of the next byte to be written. - int head_; + private int head_; /// /// Index for the tail of the buffer. /// /// Its the index of the next byte to be written. - int tail_; + private int tail_; /// /// The total number of elements added to the buffer. /// - int count_; + private int count_; /// /// Storage for the ring buffer contents. /// - byte[] array_; + private byte[] array_; - long bytesWritten_; - long bytesRead_; + private long bytesWritten_; + private long bytesRead_; - object lockObject_; + private object lockObject_; private CancellationToken? token_; - TimeSpan waitSpan_; + private TimeSpan waitSpan_; #if !SimpleSynch ManualResetEvent notEmptyEvent_; ManualResetEvent notFullEvent_; #endif - #endregion + + #endregion Instance Variables } [TestFixture] @@ -393,7 +428,8 @@ public void Basic() Assert.IsFalse(buffer_.IsFull); Assert.IsTrue(buffer_.IsEmpty); - for (int i = 0; i < buffer_.Length; ++i) { + for (int i = 0; i < buffer_.Length; ++i) + { buffer_.WriteByte(unchecked((byte)(i & 0xff))); } @@ -405,9 +441,12 @@ public void Basic() Assert.IsTrue(buffer_.IsClosed); bool caught = false; - try { + try + { buffer_.WriteByte(1); - } catch { + } + catch + { caught = true; } @@ -416,7 +455,8 @@ public void Basic() int count = Size; int expected = 0; - while (count != 0) { + while (count != 0) + { Assert.AreEqual(count, buffer_.Count); Assert.AreEqual(expected, buffer_.ReadByte()); count--; @@ -430,13 +470,13 @@ public void Basic() [Test] public void Buffered() { - const int Size = 64; buffer_ = new ReadWriteRingBuffer(Size); byte[] writeBuffer = new byte[16]; - for (int i = 0; i < 16; ++i) { + for (int i = 0; i < 16; ++i) + { writeBuffer[i] = (byte)i; } @@ -445,10 +485,10 @@ public void Buffered() byte[] readBuffer = new byte[16]; Assert.AreEqual(3, buffer_.Read(readBuffer, 0, 3)); - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) + { Assert.AreEqual(i, readBuffer[i]); } - } [Test] @@ -467,18 +507,21 @@ public void Threaded() reader.Join(); } - void Reader() + private void Reader() { var r = new Random(); byte nextValue = 0; - while (readTarget_ > 0) { + while (readTarget_ > 0) + { int thisTime = r.Next(16); - if (thisTime > readTarget_) { + if (thisTime > readTarget_) + { thisTime = readTarget_; } - while (thisTime > 0) { + while (thisTime > 0) + { int readValue = buffer_.ReadByte(); Assert.AreEqual(nextValue, readValue); nextValue = (byte)((nextValue + 1) & 0xff); @@ -487,7 +530,6 @@ void Reader() } Thread.Sleep(r.Next(10)); - } int last = buffer_.ReadByte(); @@ -496,18 +538,21 @@ void Reader() Assert.IsTrue(buffer_.IsClosed); } - void Writer() + private void Writer() { var r = new Random(); byte nextValue = 0; - while (writeTarget_ > 0) { + while (writeTarget_ > 0) + { int thisTime = r.Next(16); - if (thisTime > writeTarget_) { + if (thisTime > writeTarget_) + { thisTime = writeTarget_; } - while (thisTime > 0) { + while (thisTime > 0) + { buffer_.WriteByte(nextValue); nextValue = (byte)((nextValue + 1) & 0xff); thisTime--; @@ -518,10 +563,9 @@ void Writer() buffer_.Close(); } - int readTarget_; - int writeTarget_; - - ReadWriteRingBuffer buffer_; + private int readTarget_; + private int writeTarget_; + private ReadWriteRingBuffer buffer_; } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs index 2f006ec94..dd8dd1dd9 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs @@ -61,7 +61,8 @@ protected override void Dispose(bool disposing) /// public override void Close() { - if (isClosed_) { + if (isClosed_) + { throw new InvalidOperationException("Already closed"); } @@ -73,7 +74,8 @@ public override void Close() /// Gets a value indicating whether this instance is closed. /// /// true if this instance is closed; otherwise, false. - public bool IsClosed { + public bool IsClosed + { get { return isClosed_; } } @@ -83,15 +85,18 @@ public bool IsClosed { /// /// true if this instance is disposed; otherwise, false. /// - public bool IsDisposed { + public bool IsDisposed + { get { return isDisposed_; } } #region Instance Fields - bool isDisposed_; - bool isClosed_; - #endregion + private bool isDisposed_; + + private bool isClosed_; + + #endregion Instance Fields } /// @@ -104,8 +109,10 @@ public class MemoryStreamWithoutSeek : TrackedMemoryStream /// /// /// true if the stream is open. - public override bool CanSeek { - get { + public override bool CanSeek + { + get + { return false; } } @@ -121,7 +128,8 @@ public class NullStream : Stream /// /// /// true if the stream supports reading; otherwise, false. - public override bool CanRead { + public override bool CanRead + { get { return false; } } @@ -130,7 +138,8 @@ public override bool CanRead { /// /// /// true if the stream supports seeking; otherwise, false. - public override bool CanSeek { + public override bool CanSeek + { get { return false; } } @@ -139,7 +148,8 @@ public override bool CanSeek { /// /// /// true if the stream supports writing; otherwise, false. - public override bool CanWrite { + public override bool CanWrite + { get { return true; } } @@ -159,7 +169,8 @@ public override void Flush() /// A long value representing the length of the stream in bytes. /// A class derived from Stream does not support seeking. /// Methods were called after the stream was closed. - public override long Length { + public override long Length + { get { throw new Exception("The method or operation is not implemented."); } } @@ -171,11 +182,14 @@ public override long Length { /// An I/O error occurs. /// The stream does not support seeking. /// Methods were called after the stream was closed. - public override long Position { - get { + public override long Position + { + get + { throw new Exception("The method or operation is not implemented."); } - set { + set + { throw new Exception("The method or operation is not implemented."); } } @@ -252,7 +266,7 @@ public override void Write(byte[] buffer, int offset, int count) /// /// A that supports reading and writing from a fixed size memory buffer. - /// This provides the ability to test writing and reading from very large streams + /// This provides the ability to test writing and reading from very large streams /// without using any disk storeage /// public class WindowedStream : Stream @@ -305,7 +319,8 @@ public override void Flush() /// A long value representing the length of the stream in bytes. /// A class derived from Stream does not support seeking. /// Methods were called after the stream was closed. - public override long Length { + public override long Length + { get => throw new NotSupportedException(); } @@ -317,7 +332,8 @@ public override long Length { /// An I/O error occurs. /// The stream does not support seeking. /// Methods were called after the stream was closed. - public override long Position { + public override long Position + { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } @@ -342,14 +358,18 @@ public override long Position { public override int Read(byte[] buffer, int offset, int count) { int bytesRead = 0; - while (count > 0) { + while (count > 0) + { int value = ringBuffer.ReadByte(); - if (value >= 0) { + if (value >= 0) + { buffer[offset] = (byte)(value & 0xff); offset++; bytesRead++; count--; - } else { + } + else + { break; } } @@ -389,7 +409,8 @@ public override int Read(byte[] buffer, int offset, int count) /// Methods were called after the stream was closed. public override void Write(byte[] buffer, int offset, int count) { - for (int i = 0; i < count; ++i) { + for (int i = 0; i < count; ++i) + { ringBuffer.WriteByte(buffer[offset + i]); } } @@ -398,7 +419,8 @@ public override void Write(byte[] buffer, int offset, int count) /// Gets a value indicating whether this instance is closed. /// /// true if this instance is closed; otherwise, false. - public bool IsClosed { + public bool IsClosed + { get { return ringBuffer.IsClosed; } } @@ -406,7 +428,7 @@ public bool IsClosed { /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool disposing) { - if(disposing && !ringBuffer.IsClosed) + if (disposing && !ringBuffer.IsClosed) { ringBuffer.Close(); } @@ -426,8 +448,9 @@ protected override void Dispose(bool disposing) public long BytesRead => ringBuffer.BytesRead; #region Instance Fields + private readonly ReadWriteRingBuffer ringBuffer; - #endregion + #endregion Instance Fields } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs index 9419e54c4..5e51ff0bd 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/StringTesting.cs @@ -1,11 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; namespace ICSharpCode.SharpZipLib.Tests.TestSupport { - public static class StringTesting - { + public static class StringTesting + { static StringTesting() { AddLanguage("Chinese", "測試.txt", "big5"); diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs index 90f6b132a..9a564c3c8 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs @@ -1,7 +1,6 @@ +using NUnit.Framework; using System; using System.IO; -using System.Text; -using NUnit.Framework; namespace ICSharpCode.SharpZipLib.Tests.TestSupport { @@ -10,20 +9,23 @@ namespace ICSharpCode.SharpZipLib.Tests.TestSupport /// public static class Utils { - static Random random = new Random(); + private static Random random = new Random(); - static void Compare(byte[] a, byte[] b) + private static void Compare(byte[] a, byte[] b) { - if (a == null) { + if (a == null) + { throw new ArgumentNullException(nameof(a)); } - if (b == null) { + if (b == null) + { throw new ArgumentNullException(nameof(b)); } Assert.AreEqual(a.Length, b.Length); - for (int i = 0; i < a.Length; ++i) { + for (int i = 0; i < a.Length; ++i) + { Assert.AreEqual(a[i], b[i]); } } @@ -62,8 +64,8 @@ public TempFile() } #region IDisposable Support - private bool disposed = false; // To detect redundant calls + private bool disposed = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { @@ -85,8 +87,7 @@ protected virtual void Dispose(bool disposing) public void Dispose() => Dispose(true); - #endregion - + #endregion IDisposable Support } public class TempDir : IDisposable @@ -100,8 +101,8 @@ public TempDir() } #region IDisposable Support - private bool disposed = false; // To detect redundant calls + private bool disposed = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { @@ -133,10 +134,7 @@ internal string CreateDummyFile(string name, int size = -1) return fileName; } - #endregion - + #endregion IDisposable Support } } - - } diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/ZipTesting.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/ZipTesting.cs index 8bc44777a..688b91dc3 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/ZipTesting.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/ZipTesting.cs @@ -1,12 +1,12 @@ -using System.IO; using ICSharpCode.SharpZipLib.Zip; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.TestSupport { /// /// Provides support for testing in memory zip archives. /// - static class ZipTesting + internal static class ZipTesting { /// /// Tests the archive. @@ -27,7 +27,8 @@ public static bool TestArchive(byte[] data) public static bool TestArchive(byte[] data, string password) { using (MemoryStream ms = new MemoryStream(data)) - using (ZipFile zipFile = new ZipFile(ms)) { + using (ZipFile zipFile = new ZipFile(ms)) + { zipFile.Password = password; return zipFile.TestArchive(true); } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs index 43b524425..d983e806f 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs @@ -1,12 +1,11 @@ -using System; +using ICSharpCode.SharpZipLib.Tests.TestSupport; +using ICSharpCode.SharpZipLib.Zip; +using NUnit.Framework; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using System.Text.RegularExpressions; -using ICSharpCode.SharpZipLib.Tests.TestSupport; -using ICSharpCode.SharpZipLib.Zip; -using NUnit.Framework; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -28,12 +27,14 @@ public void Basics() string addFile = Path.Combine(tempFilePath, tempName1); MakeTempFile(addFile, 1); - try { + try + { var fastZip = new FastZip(); fastZip.CreateZip(target, tempFilePath, false, @"a\(1\)\.dat", null); var archive = new MemoryStream(target.ToArray()); - using (ZipFile zf = new ZipFile(archive)) { + using (ZipFile zf = new ZipFile(archive)) + { Assert.AreEqual(1, zf.Count); ZipEntry entry = zf[0]; Assert.AreEqual(tempName1, entry.Name); @@ -42,18 +43,21 @@ public void Basics() zf.Close(); } - } finally { + } + finally + { File.Delete(tempName1); } } - const string ZipTempDir = "SharpZipLibTest"; + private const string ZipTempDir = "SharpZipLibTest"; - void EnsureTestDirectoryIsEmpty(string baseDir) + private void EnsureTestDirectoryIsEmpty(string baseDir) { string name = Path.Combine(baseDir, ZipTempDir); - if (Directory.Exists(name)) { + if (Directory.Exists(name)) + { Directory.Delete(name, true); } @@ -73,8 +77,10 @@ public void ExtractEmptyDirectories() EnsureTestDirectoryIsEmpty(tempFilePath); string targetDir = Path.Combine(tempFilePath, ZipTempDir + @"\floyd"); - using (FileStream fs = File.Create(name)) { - using (ZipOutputStream zOut = new ZipOutputStream(fs)) { + using (FileStream fs = File.Create(name)) + { + using (ZipOutputStream zOut = new ZipOutputStream(fs)) + { zOut.PutNextEntry(new ZipEntry("floyd/")); } } @@ -101,14 +107,16 @@ public void Encryption() string addFile = Path.Combine(tempFilePath, tempName1); MakeTempFile(addFile, 1); - try { + try + { var fastZip = new FastZip(); fastZip.Password = "Ahoy"; fastZip.CreateZip(target, tempFilePath, false, @"a\.dat", null); var archive = new MemoryStream(target.ToArray()); - using (ZipFile zf = new ZipFile(archive)) { + using (ZipFile zf = new ZipFile(archive)) + { zf.Password = "Ahoy"; Assert.AreEqual(1, zf.Count); ZipEntry entry = zf[0]; @@ -117,7 +125,9 @@ public void Encryption() Assert.IsTrue(zf.TestArchive(true)); Assert.IsTrue(entry.IsCrypted); } - } finally { + } + finally + { File.Delete(tempName1); } } @@ -130,12 +140,15 @@ public void CreateExceptions() string tempFilePath = GetTempFilePath(); Assert.IsNotNull(tempFilePath, "No permission to execute this test?"); - Assert.Throws(() => + Assert.Throws(() => { string addFile = Path.Combine(tempFilePath, "test.zip"); - try { + try + { fastZip.CreateZip(addFile, @"z:\doesnt exist", false, null); - } finally { + } + finally + { File.Delete(addFile); } }); @@ -189,11 +202,10 @@ private void TestFileNames(IEnumerable names) Console.WriteLine($" - Zip entry: {entry.Name} ({nameBytes})"); } } - } } -#endregion + #endregion String testing helper [Test] [Category("Zip")] @@ -221,13 +233,12 @@ public void NonUnicodeText() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - foreach((string language, string filename, string encoding) in StringTesting.GetTestSamples()) + foreach ((string language, string filename, string encoding) in StringTesting.GetTestSamples()) { Console.WriteLine($"{language} filename \"{filename}\" using \"{encoding}\":"); ZipStrings.CodePage = Encoding.GetEncoding(encoding).CodePage; TestFileNames(filename); } - } finally { @@ -244,9 +255,12 @@ public void ExtractExceptions() Assert.IsNotNull(tempFilePath, "No permission to execute this test?"); string addFile = Path.Combine(tempFilePath, "test.zip"); - try { + try + { Assert.Throws(() => fastZip.ExtractZip(addFile, @"z:\doesnt exist", null)); - } finally { + } + finally + { File.Delete(addFile); } } @@ -265,7 +279,7 @@ public void ExtractExceptions() * but doing so would make FastZip work with locked files (that are potentially written to by others) * and silently ignoring any locks. HOWEVER: This can lead to corrupt/incomplete files, which is why it * should not be the default behavior. - * + * * Therefore I would remove this test. **/ public void ReadingOfLockedDataFiles() @@ -280,14 +294,17 @@ public void ReadingOfLockedDataFiles() string addFile = Path.Combine(tempFilePath, tempName1); MakeTempFile(addFile, 1); - try { + try + { var fastZip = new FastZip(); - using (File.Open(addFile, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)) { + using (File.Open(addFile, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)) + { fastZip.CreateZip(target, tempFilePath, false, @"a\.dat", null); var archive = new MemoryStream(target.ToArray()); - using (ZipFile zf = new ZipFile(archive)) { + using (ZipFile zf = new ZipFile(archive)) + { Assert.AreEqual(1, zf.Count); ZipEntry entry = zf[0]; Assert.AreEqual(tempName1, entry.Name); @@ -297,7 +314,9 @@ public void ReadingOfLockedDataFiles() zf.Close(); } } - } finally { + } + finally + { File.Delete(tempName1); } } @@ -317,14 +336,16 @@ public void NonAsciiPasswords() MakeTempFile(addFile, 1); string password = "abc\u0066\u0393"; - try { + try + { var fastZip = new FastZip(); fastZip.Password = password; fastZip.CreateZip(target, tempFilePath, false, @"a\.dat", null); var archive = new MemoryStream(target.ToArray()); - using (ZipFile zf = new ZipFile(archive)) { + using (ZipFile zf = new ZipFile(archive)) + { zf.Password = password; Assert.AreEqual(1, zf.Count); ZipEntry entry = zf[0]; @@ -333,12 +354,13 @@ public void NonAsciiPasswords() Assert.IsTrue(zf.TestArchive(true)); Assert.IsTrue(entry.IsCrypted); } - } finally { + } + finally + { File.Delete(tempName1); } } - [Test] [Category("Zip")] [Category("CreatesTempFile")] @@ -385,30 +407,31 @@ void CreateTestFile(string archiveFile, string contentPath) var fastZip = new FastZip(); - Assert.DoesNotThrow(() => { + Assert.DoesNotThrow(() => + { fastZip.ExtractZip(archiveFileGood, extractPath, ""); }, "Threw exception on good file name"); Assert.IsTrue(File.Exists(extractFilePathGood), "Good output file not created"); - Assert.Throws(() => { + Assert.Throws(() => + { fastZip.ExtractZip(archiveFileBad, extractPath, ""); }, "No exception was thrown for bad file name"); Assert.IsFalse(File.Exists(extractFilePathBad), "Bad output file created"); - Assert.DoesNotThrow(() => { + Assert.DoesNotThrow(() => + { fastZip.ExtractZip(archiveFileBad, extractPath, FastZip.Overwrite.Never, null, "", "", true, true); }, "Threw exception on bad file name when traversal explicitly allowed"); Assert.IsTrue(File.Exists(extractFilePathBad), "Bad output file not created when traversal explicitly allowed"); - } finally { Directory.Delete(tempPath, true); } } - } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/GeneralHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/GeneralHandling.cs index ff8c43214..460634346 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/GeneralHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/GeneralHandling.cs @@ -1,12 +1,12 @@ -using System; +using ICSharpCode.SharpZipLib.Tests.TestSupport; +using ICSharpCode.SharpZipLib.Zip; +using NUnit.Framework; +using System; using System.IO; using System.Reflection; using System.Runtime.Serialization.Formatters.Binary; using System.Security; using System.Text; -using ICSharpCode.SharpZipLib.Tests.TestSupport; -using ICSharpCode.SharpZipLib.Zip; -using NUnit.Framework; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -16,9 +16,10 @@ namespace ICSharpCode.SharpZipLib.Tests.Zip [TestFixture] public class GeneralHandling : ZipBase { - void AddRandomDataToEntry(ZipOutputStream zipStream, int size) + private void AddRandomDataToEntry(ZipOutputStream zipStream, int size) { - if (size > 0) { + if (size > 0) + { byte[] data = new byte[size]; var rnd = new Random(); rnd.NextBytes(data); @@ -27,7 +28,7 @@ void AddRandomDataToEntry(ZipOutputStream zipStream, int size) } } - void ExerciseZip(CompressionMethod method, int compressionLevel, + private void ExerciseZip(CompressionMethod method, int compressionLevel, int size, string password, bool canSeek) { byte[] originalData = null; @@ -36,26 +37,32 @@ void ExerciseZip(CompressionMethod method, int compressionLevel, var ms = new MemoryStream(compressedData); ms.Seek(0, SeekOrigin.Begin); - using (ZipInputStream inStream = new ZipInputStream(ms)) { + using (ZipInputStream inStream = new ZipInputStream(ms)) + { byte[] decompressedData = new byte[size]; - if (password != null) { + if (password != null) + { inStream.Password = password; } ZipEntry entry2 = inStream.GetNextEntry(); - if ((entry2.Flags & 8) == 0) { + if ((entry2.Flags & 8) == 0) + { Assert.AreEqual(size, entry2.Size, "Entry size invalid"); } int currentIndex = 0; - if (size > 0) { + if (size > 0) + { int count = decompressedData.Length; - while (true) { + while (true) + { int numRead = inStream.Read(decompressedData, currentIndex, count); - if (numRead <= 0) { + if (numRead <= 0) + { break; } currentIndex += numRead; @@ -65,50 +72,61 @@ void ExerciseZip(CompressionMethod method, int compressionLevel, Assert.AreEqual(currentIndex, size, "Original and decompressed data different sizes"); - if (originalData != null) { - for (int i = 0; i < originalData.Length; ++i) { + if (originalData != null) + { + for (int i = 0; i < originalData.Length; ++i) + { Assert.AreEqual(decompressedData[i], originalData[i], "Decompressed data doesnt match original, compression level: " + compressionLevel); } } } } - string DescribeAttributes(FieldAttributes attributes) + private string DescribeAttributes(FieldAttributes attributes) { string att = string.Empty; - if ((FieldAttributes.Public & attributes) != 0) { + if ((FieldAttributes.Public & attributes) != 0) + { att = att + "Public,"; } - if ((FieldAttributes.Static & attributes) != 0) { + if ((FieldAttributes.Static & attributes) != 0) + { att = att + "Static,"; } - if ((FieldAttributes.Literal & attributes) != 0) { + if ((FieldAttributes.Literal & attributes) != 0) + { att = att + "Literal,"; } - if ((FieldAttributes.HasDefault & attributes) != 0) { + if ((FieldAttributes.HasDefault & attributes) != 0) + { att = att + "HasDefault,"; } - if ((FieldAttributes.InitOnly & attributes) != 0) { + if ((FieldAttributes.InitOnly & attributes) != 0) + { att = att + "InitOnly,"; } - if ((FieldAttributes.Assembly & attributes) != 0) { + if ((FieldAttributes.Assembly & attributes) != 0) + { att = att + "Assembly,"; } - if ((FieldAttributes.FamANDAssem & attributes) != 0) { + if ((FieldAttributes.FamANDAssem & attributes) != 0) + { att = att + "FamANDAssembly,"; } - if ((FieldAttributes.FamORAssem & attributes) != 0) { + if ((FieldAttributes.FamORAssem & attributes) != 0) + { att = att + "FamORAssembly,"; } - if ((FieldAttributes.HasFieldMarshal & attributes) != 0) { + if ((FieldAttributes.HasFieldMarshal & attributes) != 0) + { att = att + "HasFieldMarshal,"; } @@ -148,11 +166,13 @@ public void InvalidPasswordSeekable() ZipEntry entry2 = inStream.GetNextEntry(); - Assert.Throws(() => + Assert.Throws(() => { - while (true) { + while (true) + { int numRead = inStream.Read(buf2, pos, buf2.Length); - if (numRead <= 0) { + if (numRead <= 0) + { break; } pos += numRead; @@ -182,10 +202,12 @@ public void ExerciseGetNextEntry() var ms = new MemoryStream(compressedData); ms.Seek(0, SeekOrigin.Begin); - using (ZipInputStream inStream = new ZipInputStream(ms)) { + using (ZipInputStream inStream = new ZipInputStream(ms)) + { byte[] buffer = new byte[10]; - while (inStream.GetNextEntry() != null) { + while (inStream.GetNextEntry() != null) + { // Read a portion of the data, so GetNextEntry has some work to do. inStream.Read(buffer, 0, 10); } @@ -213,11 +235,13 @@ public void InvalidPasswordNonSeekable() ZipEntry entry2 = inStream.GetNextEntry(); - Assert.Throws(() => + Assert.Throws(() => { - while (true) { + while (true) + { int numRead = inStream.Read(buf2, pos, buf2.Length); - if (numRead <= 0) { + if (numRead <= 0) + { break; } pos += numRead; @@ -281,7 +305,8 @@ public void CloseOnlyHandled() [Category("Zip")] public void BasicDeflated() { - for (int i = 0; i <= 9; ++i) { + for (int i = 0; i <= 9; ++i) + { ExerciseZip(CompressionMethod.Deflated, i, 50000, null, true); } } @@ -294,7 +319,8 @@ public void BasicDeflated() [Category("Zip")] public void BasicDeflatedNonSeekable() { - for (int i = 0; i <= 9; ++i) { + for (int i = 0; i <= 9; ++i) + { ExerciseZip(CompressionMethod.Deflated, i, 50000, null, false); } } @@ -330,7 +356,8 @@ public void StoredNonSeekableKnownSizeNoCrc() MemoryStream ms = new MemoryStreamWithoutSeek(); - using (ZipOutputStream outStream = new ZipOutputStream(ms)) { + using (ZipOutputStream outStream = new ZipOutputStream(ms)) + { outStream.Password = Password; outStream.IsStreamOwner = false; var entry = new ZipEntry("dummyfile.tst"); @@ -354,7 +381,8 @@ public void StoredNonSeekableKnownSizeNoCrc() // throws up buffering problems including with encryption the original // source for this change. int index = 0; - while (size > 0) { + while (size > 0) + { int count = (size > 0x200) ? 0x200 : size; outStream.Write(original, index, count); size -= 0x200; @@ -374,7 +402,8 @@ public void StoredNonSeekableKnownSizeNoCrcEncrypted() MemoryStream ms = new MemoryStreamWithoutSeek(); - using (ZipOutputStream outStream = new ZipOutputStream(ms)) { + using (ZipOutputStream outStream = new ZipOutputStream(ms)) + { outStream.Password = Password; outStream.IsStreamOwner = false; var entry = new ZipEntry("dummyfile.tst"); @@ -398,7 +427,8 @@ public void StoredNonSeekableKnownSizeNoCrcEncrypted() // throws up buffering problems including with encryption the original // source for this change. int index = 0; - while (size > 0) { + while (size > 0) + { int count = (size > 0x200) ? 0x200 : size; outStream.Write(original, index, count); size -= 0x200; @@ -416,7 +446,8 @@ public void StoredNonSeekableKnownSizeNoCrcEncrypted() [Category("Zip")] public void BasicDeflatedEncrypted() { - for (int i = 0; i <= 9; ++i) { + for (int i = 0; i <= 9; ++i) + { ExerciseZip(CompressionMethod.Deflated, i, 50157, "Rosebud", true); } } @@ -429,7 +460,8 @@ public void BasicDeflatedEncrypted() [Category("Zip")] public void BasicDeflatedEncryptedNonSeekable() { - for (int i = 0; i <= 9; ++i) { + for (int i = 0; i <= 9; ++i) + { ExerciseZip(CompressionMethod.Deflated, i, 50000, "Rosebud", false); } } @@ -451,7 +483,8 @@ public void SkipEncryptedEntriesWithoutSettingPassword() var ms = new MemoryStream(compressedData); var inStream = new ZipInputStream(ms); - while (inStream.GetNextEntry() != null) { + while (inStream.GetNextEntry() != null) + { } inStream.Close(); @@ -469,7 +502,8 @@ public void MixedEncryptedAndPlain() ); var ms = new MemoryStream(compressedData); - using (ZipInputStream inStream = new ZipInputStream(ms)) { + using (ZipInputStream inStream = new ZipInputStream(ms)) + { inStream.Password = "1234"; int extractCount = 0; @@ -477,12 +511,15 @@ public void MixedEncryptedAndPlain() ZipEntry entry; byte[] decompressedData = new byte[100]; - while ((entry = inStream.GetNextEntry()) != null) { + while ((entry = inStream.GetNextEntry()) != null) + { extractCount = decompressedData.Length; extractIndex = 0; - while (true) { + while (true) + { int numRead = inStream.Read(decompressedData, extractIndex, extractCount); - if (numRead <= 0) { + if (numRead <= 0) + { break; } extractIndex += numRead; @@ -554,7 +591,6 @@ public void StoredNonSeekableConvertToDeflate() // const int target = 65537; // MemoryStream ms = new MemoryStream(); // using (ZipOutputStream s = new ZipOutputStream(ms)) { - // for (int i = 0; i < target; ++i) { // s.PutNextEntry(new ZipEntry("dummyfile.tst")); // } @@ -575,7 +611,8 @@ public void StoredNonSeekableConvertToDeflate() public void Stream_UnicodeEntries() { var ms = new MemoryStream(); - using (ZipOutputStream s = new ZipOutputStream(ms)) { + using (ZipOutputStream s = new ZipOutputStream(ms)) + { s.IsStreamOwner = false; string sampleName = "\u03A5\u03d5\u03a3"; @@ -586,7 +623,8 @@ public void Stream_UnicodeEntries() s.Finish(); ms.Seek(0, SeekOrigin.Begin); - using (ZipInputStream zis = new ZipInputStream(ms)) { + using (ZipInputStream zis = new ZipInputStream(ms)) + { ZipEntry ze = zis.GetNextEntry(); Assert.AreEqual(sampleName, ze.Name, "Expected name to match original"); Assert.IsTrue(ze.IsUnicodeText, "Expected IsUnicodeText flag to be set"); @@ -602,11 +640,13 @@ public void PartialStreamClosing() string tempFile = GetTempFilePath(); Assert.IsNotNull(tempFile, "No permission to execute this test?"); - if (tempFile != null) { + if (tempFile != null) + { tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); MakeZipFile(tempFile, new String[] { "Farriera", "Champagne", "Urban myth" }, 10, "Aha"); - using (ZipFile zipFile = new ZipFile(tempFile)) { + using (ZipFile zipFile = new ZipFile(tempFile)) + { Stream stream = zipFile.GetInputStream(0); stream.Close(); @@ -617,29 +657,34 @@ public void PartialStreamClosing() } } - void TestLargeZip(string tempFile, int targetFiles) + private void TestLargeZip(string tempFile, int targetFiles) { const int BlockSize = 4096; byte[] data = new byte[BlockSize]; byte nextValue = 0; - for (int i = 0; i < BlockSize; ++i) { + for (int i = 0; i < BlockSize; ++i) + { nextValue = ScatterValue(nextValue); data[i] = nextValue; } - using (ZipFile zFile = new ZipFile(tempFile)) { + using (ZipFile zFile = new ZipFile(tempFile)) + { Assert.AreEqual(targetFiles, zFile.Count); byte[] readData = new byte[BlockSize]; int readIndex; - foreach (ZipEntry ze in zFile) { + foreach (ZipEntry ze in zFile) + { Stream s = zFile.GetInputStream(ze); readIndex = 0; - while (readIndex < readData.Length) { + while (readIndex < readData.Length) + { readIndex += s.Read(readData, readIndex, data.Length - readIndex); } - for (int ii = 0; ii < BlockSize; ++ii) { + for (int ii = 0; ii < BlockSize; ++ii) + { Assert.AreEqual(data[ii], readData[ii]); } } @@ -663,10 +708,13 @@ public void TestLargeZipFile() public void MakeLargeZipFile() { string tempFile = null; - try { + try + { // tempFile = Path.GetTempPath(); tempFile = @"g:\\tmp"; - } catch (SecurityException) { + } + catch (SecurityException) + { } Assert.IsNotNull(tempFile, "No permission to execute this test?"); @@ -675,25 +723,30 @@ public void MakeLargeZipFile() byte[] data = new byte[blockSize]; byte nextValue = 0; - for (int i = 0; i < blockSize; ++i) { + for (int i = 0; i < blockSize; ++i) + { nextValue = ScatterValue(nextValue); data[i] = nextValue; } tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); Console.WriteLine("Starting at {0}", DateTime.Now); - try { + try + { // MakeZipFile(tempFile, new String[] {"1", "2" }, int.MaxValue, "C1"); - using (FileStream fs = File.Create(tempFile)) { + using (FileStream fs = File.Create(tempFile)) + { var zOut = new ZipOutputStream(fs); zOut.SetLevel(4); const int TargetFiles = 8100; - for (int i = 0; i < TargetFiles; ++i) { + for (int i = 0; i < TargetFiles; ++i) + { var e = new ZipEntry(i.ToString()); e.CompressionMethod = CompressionMethod.Stored; zOut.PutNextEntry(e); - for (int block = 0; block < 128; ++block) { + for (int block = 0; block < 128; ++block) + { zOut.Write(data, 0, blockSize); } } @@ -702,7 +755,9 @@ public void MakeLargeZipFile() TestLargeZip(tempFile, TargetFiles); } - } finally { + } + finally + { Console.WriteLine("Starting at {0}", DateTime.Now); // File.Delete(tempFile); } @@ -721,7 +776,8 @@ public void SerializedObjectZeroLength() object data = new byte[0]; // Thisa wont be zero length here due to serialisation. - try { + try + { byte[] zipped = ZipZeroLength(data); object o = UnZipZeroLength(zipped); @@ -730,8 +786,9 @@ public void SerializedObjectZeroLength() Assert.IsNotNull(returned, "Expected a byte[]"); Assert.AreEqual(0, returned.Length); - - } catch (ArgumentOutOfRangeException) { + } + catch (ArgumentOutOfRangeException) + { exception = true; } @@ -764,12 +821,13 @@ public void SerializedObject() Assert.AreEqual(sampleString, returnedString); } - byte[] ZipZeroLength(object data) + private byte[] ZipZeroLength(object data) { var formatter = new BinaryFormatter(); var memStream = new MemoryStream(); - using (ZipOutputStream zipStream = new ZipOutputStream(memStream)) { + using (ZipOutputStream zipStream = new ZipOutputStream(memStream)) + { zipStream.PutNextEntry(new ZipEntry("data")); formatter.Serialize(zipStream, data); zipStream.CloseEntry(); @@ -782,18 +840,21 @@ byte[] ZipZeroLength(object data) return result; } - object UnZipZeroLength(byte[] zipped) + private object UnZipZeroLength(byte[] zipped) { - if (zipped == null) { + if (zipped == null) + { return null; } object result = null; var formatter = new BinaryFormatter(); var memStream = new MemoryStream(zipped); - using (ZipInputStream zipStream = new ZipInputStream(memStream)) { + using (ZipInputStream zipStream = new ZipInputStream(memStream)) + { ZipEntry zipEntry = zipStream.GetNextEntry(); - if (zipEntry != null) { + if (zipEntry != null) + { result = formatter.Deserialize(zipStream); } zipStream.Close(); @@ -803,7 +864,7 @@ object UnZipZeroLength(byte[] zipped) return result; } - void CheckNameConversion(string toCheck) + private void CheckNameConversion(string toCheck) { byte[] intermediate = ZipStrings.ConvertToArray(toCheck); string final = ZipStrings.ConvertToString(intermediate); @@ -858,7 +919,8 @@ public void PasswordCheckingWithDateInExtraData() var ms = new MemoryStream(); var checkTime = new DateTimeOffset(2010, 10, 16, 0, 3, 28, new TimeSpan(1, 0, 0)); - using (ZipOutputStream zos = new ZipOutputStream(ms)) { + using (ZipOutputStream zos = new ZipOutputStream(ms)) + { zos.IsStreamOwner = false; zos.Password = "secret"; var ze = new ZipEntry("uno"); @@ -881,7 +943,8 @@ public void PasswordCheckingWithDateInExtraData() } ms.Position = 0; - using (ZipInputStream zis = new ZipInputStream(ms)) { + using (ZipInputStream zis = new ZipInputStream(ms)) + { zis.Password = "secret"; ZipEntry uno = zis.GetNextEntry(); var theByte = (byte)zis.ReadByte(); diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs index 2d3eeb478..43676f77b 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs @@ -1,9 +1,7 @@ -using System; -using System.IO; -using ICSharpCode.SharpZipLib.Tests.TestSupport; +using ICSharpCode.SharpZipLib.Tests.TestSupport; using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; -using System.Threading; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -13,12 +11,15 @@ namespace ICSharpCode.SharpZipLib.Tests.Zip [TestFixture] public class StreamHandling : ZipBase { - void MustFailRead(Stream s, byte[] buffer, int offset, int count) + private void MustFailRead(Stream s, byte[] buffer, int offset, int count) { bool exception = false; - try { + try + { s.Read(buffer, offset, count); - } catch { + } + catch + { exception = true; } Assert.IsTrue(exception, "Read should fail"); @@ -93,7 +94,8 @@ public void Zip64Descriptor() public void ReadAndWriteZip64NonSeekable() { MemoryStream msw = new MemoryStreamWithoutSeek(); - using (ZipOutputStream outStream = new ZipOutputStream(msw)) { + using (ZipOutputStream outStream = new ZipOutputStream(msw)) + { outStream.UseZip64 = UseZip64.On; outStream.IsStreamOwner = false; @@ -110,12 +112,15 @@ public void ReadAndWriteZip64NonSeekable() msw.Position = 0; - using (ZipInputStream zis = new ZipInputStream(msw)) { - while (zis.GetNextEntry() != null) { + using (ZipInputStream zis = new ZipInputStream(msw)) + { + while (zis.GetNextEntry() != null) + { int len = 0; int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; - while ((len = zis.Read(buffer, 0, bufferSize)) > 0) { + while ((len = zis.Read(buffer, 0, bufferSize)) > 0) + { // Reading the data is enough } } @@ -143,6 +148,7 @@ public void EntryWithNoDataAndZip64() Assert.IsTrue(ZipTesting.TestArchive(msw.ToArray())); } + /// /// Empty zip entries can be created and read? /// @@ -154,7 +160,8 @@ public void EmptyZipEntries() var ms = new MemoryStream(); var outStream = new ZipOutputStream(ms); - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) + { outStream.PutNextEntry(new ZipEntry(i.ToString())); } @@ -167,10 +174,13 @@ public void EmptyZipEntries() int extractCount = 0; byte[] decompressedData = new byte[100]; - while ((inStream.GetNextEntry()) != null) { - while (true) { + while ((inStream.GetNextEntry()) != null) + { + while (true) + { int numRead = inStream.Read(decompressedData, extractCount, decompressedData.Length); - if (numRead <= 0) { + if (numRead <= 0) + { break; } extractCount += numRead; @@ -194,7 +204,8 @@ public void CreateAndReadEmptyZip() ms.Seek(0, SeekOrigin.Begin); var inStream = new ZipInputStream(ms); - while ((inStream.GetNextEntry()) != null) { + while ((inStream.GetNextEntry()) != null) + { Assert.Fail("No entries should be found in empty zip"); } } @@ -209,7 +220,8 @@ public void BaseClosedWhenOwner() Assert.IsFalse(ms.IsClosed, "Underlying stream should NOT be closed"); - using (ZipOutputStream stream = new ZipOutputStream(ms)) { + using (ZipOutputStream stream = new ZipOutputStream(ms)) + { Assert.IsTrue(stream.IsStreamOwner, "Should be stream owner by default"); } @@ -226,7 +238,8 @@ public void BaseNotClosedWhenNotOwner() Assert.IsFalse(ms.IsClosed, "Underlying stream should NOT be closed"); - using (ZipOutputStream stream = new ZipOutputStream(ms)) { + using (ZipOutputStream stream = new ZipOutputStream(ms)) + { Assert.IsTrue(stream.IsStreamOwner, "Should be stream owner by default"); stream.IsStreamOwner = false; } @@ -243,19 +256,26 @@ public void BaseClosedAfterFailure() Assert.IsFalse(ms.IsClosed, "Underlying stream should NOT be closed initially"); bool blewUp = false; - try { - using (ZipOutputStream stream = new ZipOutputStream(ms)) { + try + { + using (ZipOutputStream stream = new ZipOutputStream(ms)) + { Assert.IsTrue(stream.IsStreamOwner, "Should be stream owner by default"); - try { + try + { stream.PutNextEntry(new ZipEntry("Tiny")); stream.Write(new byte[32], 0, 32); - } finally { + } + finally + { Assert.IsFalse(ms.IsClosed, "Stream should still not be closed."); stream.Close(); Assert.Fail("Exception not thrown"); } } - } catch { + } + catch + { blewUp = true; } @@ -277,7 +297,7 @@ public void WriteThroughput() }); } - [Test] + [Test] [Category("Zip")] [Category("Performance")] [Explicit("Long Running")] @@ -304,6 +324,5 @@ public void SingleLargeEntry() } ); } - } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/WindowsNameTransformHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/WindowsNameTransformHandling.cs index 6eccd9d95..7e7d440be 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/WindowsNameTransformHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/WindowsNameTransformHandling.cs @@ -1,7 +1,7 @@ -using System; -using System.IO; -using ICSharpCode.SharpZipLib.Zip; +using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -36,10 +36,13 @@ public void NameTooLong() { var wnt = new WindowsNameTransform(); var veryLong = new string('x', 261); - try { + try + { wnt.TransformDirectory(veryLong); Assert.Fail("Expected an exception"); - } catch (PathTooLongException) { + } + catch (PathTooLongException) + { } } @@ -48,9 +51,12 @@ public void LengthBoundaryOk() { var wnt = new WindowsNameTransform(); string veryLong = "c:\\" + new string('x', 260); - try { + try + { string transformed = wnt.TransformDirectory(veryLong); - } catch { + } + catch + { Assert.Fail("Expected no exception"); } } @@ -59,34 +65,49 @@ public void LengthBoundaryOk() public void ReplacementChecking() { var wnt = new WindowsNameTransform(); - try { + try + { wnt.Replacement = '*'; Assert.Fail("Expected an exception"); - } catch (ArgumentException) { + } + catch (ArgumentException) + { } - try { + try + { wnt.Replacement = '?'; Assert.Fail("Expected an exception"); - } catch (ArgumentException) { + } + catch (ArgumentException) + { } - try { + try + { wnt.Replacement = ':'; Assert.Fail("Expected an exception"); - } catch (ArgumentException) { + } + catch (ArgumentException) + { } - try { + try + { wnt.Replacement = '/'; Assert.Fail("Expected an exception"); - } catch (ArgumentException) { + } + catch (ArgumentException) + { } - try { + try + { wnt.Replacement = '\\'; Assert.Fail("Expected an exception"); - } catch (ArgumentException) { + } + catch (ArgumentException) + { } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs index cef7e7985..6d4c3d74b 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs @@ -1,7 +1,6 @@ using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; @@ -9,8 +8,8 @@ namespace ICSharpCode.SharpZipLib.Tests.Zip { [TestFixture] - public class ZipEncryptionHandling - { + public class ZipEncryptionHandling + { [Test] [Category("Encryption")] [Category("Zip")] @@ -46,8 +45,8 @@ public void ZipFileAesDecryption() foreach (ZipEntry entry in zipFile) { if (!entry.IsFile) continue; - - using(var zis = zipFile.GetInputStream(entry)) + + using (var zis = zipFile.GetInputStream(entry)) using (var sr = new StreamReader(zis, Encoding.UTF8)) { var content = sr.ReadToEnd(); @@ -145,7 +144,6 @@ public void CreateZipWithEncryptedEntries(string password, int keySize) try { - using (var fs = File.OpenWrite(fileName)) { ms.CopyTo(fs); @@ -158,7 +156,6 @@ public void CreateZipWithEncryptedEntries(string password, int keySize) } Assert.AreEqual(0, p.ExitCode, "Archive verification failed"); - } finally { @@ -170,12 +167,11 @@ public void CreateZipWithEncryptedEntries(string password, int keySize) Assert.Warn("Skipping file verification since 7za is not in path"); } } - } - const string DummyDataString = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. -Fusce bibendum diam ac nunc rutrum ornare. Maecenas blandit elit ligula, eget suscipit lectus rutrum eu. -Maecenas aliquam, purus mattis pulvinar pharetra, nunc orci maximus justo, sed facilisis massa dui sed lorem. + private const string DummyDataString = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Fusce bibendum diam ac nunc rutrum ornare. Maecenas blandit elit ligula, eget suscipit lectus rutrum eu. +Maecenas aliquam, purus mattis pulvinar pharetra, nunc orci maximus justo, sed facilisis massa dui sed lorem. Vestibulum id iaculis leo. Duis porta ante lorem. Duis condimentum enim nec lorem tristique interdum. Fusce in faucibus libero."; } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryFactoryHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryFactoryHandling.cs index 8066a1934..ab2ae3744 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryFactoryHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryFactoryHandling.cs @@ -1,7 +1,7 @@ -using System; -using System.IO; -using ICSharpCode.SharpZipLib.Zip; +using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -94,18 +94,20 @@ public void CreatedValues() tempDir = Path.Combine(tempDir, "SharpZipTest"); - if (tempDir != null) { - + if (tempDir != null) + { Directory.CreateDirectory(tempDir); - try { + try + { // Note the seconds returned will be even! var createTime = new DateTime(2100, 2, 27, 11, 07, 56); var lastWriteTime = new DateTime(2050, 11, 3, 7, 23, 32); var lastAccessTime = new DateTime(2050, 11, 3, 0, 42, 12); string tempFile = Path.Combine(tempDir, "SharpZipTest.Zip"); - using (FileStream f = File.Create(tempFile, 1024)) { + using (FileStream f = File.Create(tempFile, 1024)) + { f.WriteByte(0); } @@ -120,7 +122,8 @@ public void CreatedValues() ZipEntry entry; int combinedAttributes = 0; - try { + try + { factory = new ZipEntryFactory(); factory.Setting = ZipEntryFactory.TimeSetting.CreateTime; @@ -142,7 +145,9 @@ public void CreatedValues() entry = factory.MakeFileEntry(tempFile); Assert.AreEqual(lastWriteTime, entry.DateTime, "Write time failure"); Assert.AreEqual(1, entry.Size); - } finally { + } + finally + { File.Delete(tempFile); } @@ -168,7 +173,9 @@ public void CreatedValues() factory.Setting = ZipEntryFactory.TimeSetting.LastWriteTime; entry = factory.MakeDirectoryEntry(tempDir); Assert.AreEqual(lastWriteTime, entry.DateTime, "Directory write time failure"); - } finally { + } + finally + { Directory.Delete(tempDir, true); } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryHandling.cs index 9e126e3df..2babfafd2 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEntryHandling.cs @@ -1,20 +1,21 @@ -using System; +using ICSharpCode.SharpZipLib.Tests.TestSupport; +using ICSharpCode.SharpZipLib.Zip; +using NUnit.Framework; +using System; using System.IO; using System.Reflection; using System.Text; -using ICSharpCode.SharpZipLib.Tests.TestSupport; -using ICSharpCode.SharpZipLib.Zip; -using NUnit.Framework; namespace ICSharpCode.SharpZipLib.Tests.Zip { [TestFixture] public class ZipEntryHandling : ZipBase { - byte[] MakeLocalHeader(string asciiName, short versionToExtract, short flags, short method, + private byte[] MakeLocalHeader(string asciiName, short versionToExtract, short flags, short method, int dostime, int crc, int compressedSize, int size) { - using (TrackedMemoryStream ms = new TrackedMemoryStream()) { + using (TrackedMemoryStream ms = new TrackedMemoryStream()) + { ms.WriteByte((byte)'P'); ms.WriteByte((byte)'K'); ms.WriteByte(3); @@ -36,7 +37,7 @@ byte[] MakeLocalHeader(string asciiName, short versionToExtract, short flags, sh } } - ZipEntry MakeEntry(string asciiName, short versionToExtract, short flags, short method, + private ZipEntry MakeEntry(string asciiName, short versionToExtract, short flags, short method, int dostime, int crc, int compressedSize, int size) { byte[] data = MakeLocalHeader(asciiName, versionToExtract, flags, method, @@ -48,7 +49,7 @@ ZipEntry MakeEntry(string asciiName, short versionToExtract, short flags, short return ze; } - void PiecewiseCompare(ZipEntry lhs, ZipEntry rhs) + private void PiecewiseCompare(ZipEntry lhs, ZipEntry rhs) { Type entryType = typeof(ZipEntry); BindingFlags binding = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; @@ -57,7 +58,8 @@ void PiecewiseCompare(ZipEntry lhs, ZipEntry rhs) Assert.Greater(fields.Length, 8, "Failed to find fields"); - foreach (FieldInfo info in fields) { + foreach (FieldInfo info in fields) + { object lValue = info.GetValue(lhs); object rValue = info.GetValue(rhs); diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipExtraDataHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipExtraDataHandling.cs index 6a0416a11..870050507 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipExtraDataHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipExtraDataHandling.cs @@ -1,7 +1,7 @@ -using System; -using System.IO; -using ICSharpCode.SharpZipLib.Zip; +using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -41,9 +41,12 @@ public void ExceedSize() Assert.AreEqual(65535, zed.Length); bool caught = false; - try { + try + { zed.AddEntry(3, null); - } catch { + } + catch + { caught = true; } @@ -54,9 +57,12 @@ public void ExceedSize() Assert.AreEqual(65510, zed.Length); caught = false; - try { + try + { zed.AddEntry(2, new byte[22]); - } catch { + } + catch + { caught = true; } Assert.IsTrue(caught, "Expected an exception when max size exceeded"); @@ -115,7 +121,8 @@ public void BasicOperations() zed2.AddEntry(1, new byte[] { }); byte[] data = zed.GetEntryData(); - for (int i = 0; i < data.Length; ++i) { + for (int i = 0; i < data.Length; ++i) + { Assert.AreEqual(zed2.GetEntryData()[i], data[i]); } @@ -136,14 +143,16 @@ public void BasicOperations() findResult = zed.Find(1); Assert.IsTrue(findResult, "B - Should find tag 1"); Assert.AreEqual(3, zed.ValueLength, "B - Length of entry should be 3"); - for (int i = 1; i <= 3; ++i) { + for (int i = 1; i <= 3; ++i) + { Assert.AreEqual(i, zed.ReadByte()); } Assert.AreEqual(-1, zed.ReadByte()); Stream s = zed.GetStreamForTag(1); Assert.AreEqual(3, s.Length, "B.1 Stream length should be 3"); - for (int i = 1; i <= 3; ++i) { + for (int i = 1; i <= 3; ++i) + { Assert.AreEqual(i, s.ReadByte()); } Assert.AreEqual(-1, s.ReadByte()); @@ -154,7 +163,8 @@ public void BasicOperations() findResult = zed.Find(1); Assert.IsTrue(findResult, "C.1 - Should find tag 1"); Assert.AreEqual(3, zed.ValueLength, "C.1 - Length of entry should be 3"); - for (int i = 1; i <= 3; ++i) { + for (int i = 1; i <= 3; ++i) + { Assert.AreEqual(i, zed.ReadByte()); } Assert.AreEqual(-1, zed.ReadByte()); @@ -249,7 +259,8 @@ public void UnreadCountValid() zed = new ZipExtraData(new byte[] { 1, 0, 7, 0, 1, 2, 3, 4, 5, 6, 7 }); Assert.IsTrue(zed.Find(1), "Should find tag 1"); - for (int i = 0; i < 7; ++i) { + for (int i = 0; i < 7; ++i) + { Assert.AreEqual(7 - i, zed.UnreadCount); zed.ReadByte(); } @@ -287,9 +298,12 @@ public void Skipping() bool exceptionCaught = false; - try { + try + { zed.Skip(1); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Should fail to skip past end"); @@ -302,9 +316,12 @@ public void Skipping() Assert.AreEqual(4, zed.CurrentReadIndex); exceptionCaught = false; - try { + try + { zed.Skip(-1); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Should fail to skip before beginning"); @@ -320,9 +337,12 @@ public void ReadOverrunLong() // Empty Tag bool exceptionCaught = false; - try { + try + { zed.ReadLong(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -332,9 +352,12 @@ public void ReadOverrunLong() Assert.IsTrue(zed.Find(1), "Should find tag 1"); exceptionCaught = false; - try { + try + { zed.ReadLong(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -345,9 +368,12 @@ public void ReadOverrunLong() zed.ReadLong(); exceptionCaught = false; - try { + try + { zed.ReadLong(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -363,9 +389,12 @@ public void ReadOverrunInt() // Empty Tag bool exceptionCaught = false; - try { + try + { zed.ReadInt(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -375,9 +404,12 @@ public void ReadOverrunInt() Assert.IsTrue(zed.Find(1), "Should find tag 1"); exceptionCaught = false; - try { + try + { zed.ReadInt(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -388,9 +420,12 @@ public void ReadOverrunInt() zed.ReadInt(); exceptionCaught = false; - try { + try + { zed.ReadInt(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -406,9 +441,12 @@ public void ReadOverrunShort() // Empty Tag bool exceptionCaught = false; - try { + try + { zed.ReadShort(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -418,9 +456,12 @@ public void ReadOverrunShort() Assert.IsTrue(zed.Find(1), "Should find tag 1"); exceptionCaught = false; - try { + try + { zed.ReadShort(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); @@ -431,9 +472,12 @@ public void ReadOverrunShort() zed.ReadShort(); exceptionCaught = false; - try { + try + { zed.ReadShort(); - } catch (ZipException) { + } + catch (ZipException) + { exceptionCaught = true; } Assert.IsTrue(exceptionCaught, "Expected EOS exception"); diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs index cdcbcdb2d..9496938e8 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs @@ -1,10 +1,10 @@ -using System; -using System.IO; -using System.Text; -using ICSharpCode.SharpZipLib.Core; +using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Tests.TestSupport; using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; +using System; +using System.IO; +using System.Text; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -20,9 +20,12 @@ public void NullStreamDetected() bool nullStreamDetected = false; - try { + try + { bad = new ZipFile(nullStream); - } catch { + } + catch + { nullStreamDetected = true; } @@ -43,10 +46,12 @@ public void Zip64Entries() const int target = 65537; - using (ZipFile zipFile = ZipFile.Create(Path.GetTempFileName())) { + using (ZipFile zipFile = ZipFile.Create(Path.GetTempFileName())) + { zipFile.BeginUpdate(); - for (int i = 0; i < target; ++i) { + for (int i = 0; i < target; ++i) + { var ze = new ZipEntry(i.ToString()); ze.CompressedSize = 0; ze.Size = 0; @@ -64,7 +69,8 @@ public void Zip64Entries() public void EmbeddedArchive() { var memStream = new MemoryStream(); - using (ZipFile f = new ZipFile(memStream)) { + using (ZipFile f = new ZipFile(memStream)) + { f.IsStreamOwner = false; var m = new StringMemoryDataSource("0000000"); @@ -80,8 +86,10 @@ public void EmbeddedArchive() Array.Copy(rawArchive, 0, pseudoSfx, 1049, rawArchive.Length); memStream = new MemoryStream(pseudoSfx); - using (ZipFile f = new ZipFile(memStream)) { - for (int index = 0; index < f.Count; ++index) { + using (ZipFile f = new ZipFile(memStream)) + { + for (int index = 0; index < f.Count; ++index) + { Stream entryStream = f.GetInputStream(index); var data = new MemoryStream(); StreamUtils.Copy(entryStream, data, new byte[128]); @@ -96,7 +104,8 @@ public void EmbeddedArchive() public void Zip64Useage() { var memStream = new MemoryStream(); - using (ZipFile f = new ZipFile(memStream)) { + using (ZipFile f = new ZipFile(memStream)) + { f.IsStreamOwner = false; f.UseZip64 = UseZip64.On; @@ -114,8 +123,10 @@ public void Zip64Useage() Array.Copy(rawArchive, 0, pseudoSfx, 1049, rawArchive.Length); memStream = new MemoryStream(pseudoSfx); - using (ZipFile f = new ZipFile(memStream)) { - for (int index = 0; index < f.Count; ++index) { + using (ZipFile f = new ZipFile(memStream)) + { + for (int index = 0; index < f.Count; ++index) + { Stream entryStream = f.GetInputStream(index); var data = new MemoryStream(); StreamUtils.Copy(entryStream, data, new byte[128]); @@ -141,7 +152,8 @@ public void BasicEncryption() { const string TestValue = "0001000"; var memStream = new MemoryStream(); - using (ZipFile f = new ZipFile(memStream)) { + using (ZipFile f = new ZipFile(memStream)) + { f.IsStreamOwner = false; f.Password = "Hello"; @@ -152,12 +164,14 @@ public void BasicEncryption() Assert.IsTrue(f.TestArchive(true), "Archive test should pass"); } - using (ZipFile g = new ZipFile(memStream)) { + using (ZipFile g = new ZipFile(memStream)) + { g.Password = "Hello"; ZipEntry ze = g[0]; Assert.IsTrue(ze.IsCrypted, "Entry should be encrypted"); - using (StreamReader r = new StreamReader(g.GetInputStream(0))) { + using (StreamReader r = new StreamReader(g.GetInputStream(0))) + { string data = r.ReadToEnd(); Assert.AreEqual(TestValue, data); } @@ -175,7 +189,8 @@ public void BasicEncryptionToDisk() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); - using (ZipFile f = ZipFile.Create(tempFile)) { + using (ZipFile f = ZipFile.Create(tempFile)) + { f.Password = "Hello"; var m = new StringMemoryDataSource(TestValue); @@ -184,17 +199,20 @@ public void BasicEncryptionToDisk() f.CommitUpdate(); } - using (ZipFile f = new ZipFile(tempFile)) { + using (ZipFile f = new ZipFile(tempFile)) + { f.Password = "Hello"; Assert.IsTrue(f.TestArchive(true), "Archive test should pass"); } - using (ZipFile g = new ZipFile(tempFile)) { + using (ZipFile g = new ZipFile(tempFile)) + { g.Password = "Hello"; ZipEntry ze = g[0]; Assert.IsTrue(ze.IsCrypted, "Entry should be encrypted"); - using (StreamReader r = new StreamReader(g.GetInputStream(0))) { + using (StreamReader r = new StreamReader(g.GetInputStream(0))) + { string data = r.ReadToEnd(); Assert.AreEqual(TestValue, data); } @@ -209,7 +227,8 @@ public void AddEncryptedEntriesToExistingArchive() { const string TestValue = "0001000"; var memStream = new MemoryStream(); - using (ZipFile f = new ZipFile(memStream)) { + using (ZipFile f = new ZipFile(memStream)) + { f.IsStreamOwner = false; f.UseZip64 = UseZip64.Off; @@ -220,11 +239,13 @@ public void AddEncryptedEntriesToExistingArchive() Assert.IsTrue(f.TestArchive(true), "Archive test should pass"); } - using (ZipFile g = new ZipFile(memStream)) { + using (ZipFile g = new ZipFile(memStream)) + { ZipEntry ze = g[0]; Assert.IsFalse(ze.IsCrypted, "Entry should NOT be encrypted"); - using (StreamReader r = new StreamReader(g.GetInputStream(0))) { + using (StreamReader r = new StreamReader(g.GetInputStream(0))) + { string data = r.ReadToEnd(); Assert.AreEqual(TestValue, data); } @@ -241,30 +262,34 @@ public void AddEncryptedEntriesToExistingArchive() ze = g[1]; Assert.IsTrue(ze.IsCrypted, "New entry should be encrypted"); - using (StreamReader r = new StreamReader(g.GetInputStream(0))) { + using (StreamReader r = new StreamReader(g.GetInputStream(0))) + { string data = r.ReadToEnd(); Assert.AreEqual(TestValue, data); } } } - void TryDeleting(byte[] master, int totalEntries, int additions, params string[] toDelete) + private void TryDeleting(byte[] master, int totalEntries, int additions, params string[] toDelete) { var ms = new MemoryStream(); ms.Write(master, 0, master.Length); - using (ZipFile f = new ZipFile(ms)) { + using (ZipFile f = new ZipFile(ms)) + { f.IsStreamOwner = false; Assert.AreEqual(totalEntries, f.Count); Assert.IsTrue(f.TestArchive(true)); f.BeginUpdate(new MemoryArchiveStorage()); - for (int i = 0; i < additions; ++i) { + for (int i = 0; i < additions; ++i) + { f.Add(new StringMemoryDataSource("Another great file"), string.Format("Add{0}.dat", i + 1)); } - foreach (string name in toDelete) { + foreach (string name in toDelete) + { f.Delete(name); } f.CommitUpdate(); @@ -279,23 +304,26 @@ void TryDeleting(byte[] master, int totalEntries, int additions, params string[] } } - void TryDeleting(byte[] master, int totalEntries, int additions, params int[] toDelete) + private void TryDeleting(byte[] master, int totalEntries, int additions, params int[] toDelete) { var ms = new MemoryStream(); ms.Write(master, 0, master.Length); - using (ZipFile f = new ZipFile(ms)) { + using (ZipFile f = new ZipFile(ms)) + { f.IsStreamOwner = false; Assert.AreEqual(totalEntries, f.Count); Assert.IsTrue(f.TestArchive(true)); f.BeginUpdate(new MemoryArchiveStorage()); - for (int i = 0; i < additions; ++i) { + for (int i = 0; i < additions; ++i) + { f.Add(new StringMemoryDataSource("Another great file"), string.Format("Add{0}.dat", i + 1)); } - foreach (int i in toDelete) { + foreach (int i in toDelete) + { f.Delete(f[i]); } f.CommitUpdate(); @@ -319,7 +347,8 @@ public void AddAndDeleteEntriesMemory() { var memStream = new MemoryStream(); - using (ZipFile f = new ZipFile(memStream)) { + using (ZipFile f = new ZipFile(memStream)) + { f.IsStreamOwner = false; f.BeginUpdate(new MemoryArchiveStorage()); @@ -376,7 +405,8 @@ public void AddAndDeleteEntries() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); - using (ZipFile f = ZipFile.Create(tempFile)) { + using (ZipFile f = ZipFile.Create(tempFile)) + { f.BeginUpdate(); f.Add(addFile); f.Add(addFile2); @@ -384,7 +414,8 @@ public void AddAndDeleteEntries() Assert.IsTrue(f.TestArchive(true)); } - using (ZipFile f = new ZipFile(tempFile)) { + using (ZipFile f = new ZipFile(tempFile)) + { Assert.AreEqual(2, f.Count); Assert.IsTrue(f.TestArchive(true)); f.BeginUpdate(); @@ -412,17 +443,22 @@ public void RoundTrip() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); - try { + try + { MakeZipFile(tempFile, "", 10, 1024, ""); - using (ZipFile zipFile = new ZipFile(tempFile)) { - foreach (ZipEntry e in zipFile) { + using (ZipFile zipFile = new ZipFile(tempFile)) + { + foreach (ZipEntry e in zipFile) + { Stream instream = zipFile.GetInputStream(e); CheckKnownEntry(instream, 1024); } zipFile.Close(); } - } finally { + } + finally + { File.Delete(tempFile); } } @@ -437,8 +473,10 @@ public void RoundTripInMemory() var storage = new MemoryStream(); MakeZipFile(storage, false, "", 10, 1024, ""); - using (ZipFile zipFile = new ZipFile(storage)) { - foreach (ZipEntry e in zipFile) { + using (ZipFile zipFile = new ZipFile(storage)) + { + foreach (ZipEntry e in zipFile) + { Stream instream = zipFile.GetInputStream(e); CheckKnownEntry(instream, 1024); } @@ -457,10 +495,12 @@ public void AddToEmptyArchive() MakeTempFile(addFile, 1); - try { + try + { tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); - using (ZipFile f = ZipFile.Create(tempFile)) { + using (ZipFile f = ZipFile.Create(tempFile)) + { f.BeginUpdate(); f.Add(addFile); f.CommitUpdate(); @@ -468,7 +508,8 @@ public void AddToEmptyArchive() Assert.IsTrue(f.TestArchive(true)); } - using (ZipFile f = new ZipFile(tempFile)) { + using (ZipFile f = new ZipFile(tempFile)) + { Assert.AreEqual(1, f.Count); f.BeginUpdate(); f.Delete(f[0]); @@ -479,7 +520,9 @@ public void AddToEmptyArchive() } File.Delete(tempFile); - } finally { + } + finally + { File.Delete(addFile); } } @@ -493,14 +536,16 @@ public void CreateEmptyArchive() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); - using (ZipFile f = ZipFile.Create(tempFile)) { + using (ZipFile f = ZipFile.Create(tempFile)) + { f.BeginUpdate(); f.CommitUpdate(); Assert.IsTrue(f.TestArchive(true)); f.Close(); } - using (ZipFile f = new ZipFile(tempFile)) { + using (ZipFile f = new ZipFile(tempFile)) + { Assert.AreEqual(0, f.Count); } @@ -522,15 +567,20 @@ public void FindEntriesInArchiveWithLongComment() var longComment = new String('A', 65535); MakeZipFile(tempFile, "", 1, 1, longComment); - try { - using (ZipFile zipFile = new ZipFile(tempFile)) { - foreach (ZipEntry e in zipFile) { + try + { + using (ZipFile zipFile = new ZipFile(tempFile)) + { + foreach (ZipEntry e in zipFile) + { Stream instream = zipFile.GetInputStream(e); CheckKnownEntry(instream, 1); } zipFile.Close(); } - } finally { + } + finally + { File.Delete(tempFile); } } @@ -558,15 +608,20 @@ public void FindEntriesInArchiveExtraData() tempStream.Close(); bool fails = false; - try { - using (ZipFile zipFile = new ZipFile(tempFile)) { - foreach (ZipEntry e in zipFile) { + try + { + using (ZipFile zipFile = new ZipFile(tempFile)) + { + foreach (ZipEntry e in zipFile) + { Stream instream = zipFile.GetInputStream(e); CheckKnownEntry(instream, 1); } zipFile.Close(); } - } catch { + } + catch + { fails = true; } @@ -588,7 +643,8 @@ public void FindEntry() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); MakeZipFile(tempFile, new string[] { "Farriera", "Champagne", "Urban myth" }, 10, "Aha"); - using (ZipFile zipFile = new ZipFile(tempFile)) { + using (ZipFile zipFile = new ZipFile(tempFile)) + { Assert.AreEqual(3, zipFile.Count, "Expected 1 entry"); int testIndex = zipFile.FindEntry("Farriera", false); @@ -631,7 +687,8 @@ public void HandlesNoEntries() tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); MakeZipFile(tempFile, "", 0, 1, "Aha"); - using (ZipFile zipFile = new ZipFile(tempFile)) { + using (ZipFile zipFile = new ZipFile(tempFile)) + { Assert.AreEqual(0, zipFile.Count); zipFile.Close(); } @@ -650,8 +707,8 @@ public void ArchiveTesting() var ms = new MemoryStream(compressedData); ms.Seek(0, SeekOrigin.Begin); - using (ZipFile testFile = new ZipFile(ms)) { - + using (ZipFile testFile = new ZipFile(ms)) + { Assert.IsTrue(testFile.TestArchive(true), "Unexpected error in archive detected"); byte[] corrupted = new byte[compressedData.Length]; @@ -661,12 +718,13 @@ public void ArchiveTesting() ms = new MemoryStream(corrupted); } - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { Assert.IsFalse(testFile.TestArchive(true), "Error in archive not detected"); } } - void TestDirectoryEntry(MemoryStream s) + private void TestDirectoryEntry(MemoryStream s) { var outStream = new ZipOutputStream(s); outStream.IsStreamOwner = false; @@ -674,7 +732,8 @@ void TestDirectoryEntry(MemoryStream s) outStream.Close(); var ms2 = new MemoryStream(s.ToArray()); - using (ZipFile zf = new ZipFile(ms2)) { + using (ZipFile zf = new ZipFile(ms2)) + { Assert.IsTrue(zf.TestArchive(true)); } } @@ -687,7 +746,7 @@ public void TestDirectoryEntry() TestDirectoryEntry(new MemoryStreamWithoutSeek()); } - void TestEncryptedDirectoryEntry(MemoryStream s) + private void TestEncryptedDirectoryEntry(MemoryStream s) { var outStream = new ZipOutputStream(s); outStream.Password = "Tonto hand me a beer"; @@ -697,7 +756,8 @@ void TestEncryptedDirectoryEntry(MemoryStream s) outStream.Close(); var ms2 = new MemoryStream(s.ToArray()); - using (ZipFile zf = new ZipFile(ms2)) { + using (ZipFile zf = new ZipFile(ms2)) + { Assert.IsTrue(zf.TestArchive(true)); } } @@ -718,7 +778,8 @@ public void Crypto_AddEncryptedEntryToExistingArchiveSafe() byte[] rawData; - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { testFile.IsStreamOwner = false; testFile.BeginUpdate(); testFile.Add(new StringMemoryDataSource("Aha"), "No1", CompressionMethod.Stored); @@ -732,7 +793,8 @@ public void Crypto_AddEncryptedEntryToExistingArchiveSafe() ms = new MemoryStream(rawData); - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { Assert.IsTrue(testFile.TestArchive(true)); testFile.BeginUpdate(new MemoryArchiveStorage(FileUpdateMode.Safe)); @@ -754,7 +816,8 @@ public void Crypto_AddEncryptedEntryToExistingArchiveDirect() { var ms = new MemoryStream(); - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { testFile.IsStreamOwner = false; testFile.BeginUpdate(); testFile.Add(new StringMemoryDataSource("Aha"), "No1", CompressionMethod.Stored); @@ -765,7 +828,8 @@ public void Crypto_AddEncryptedEntryToExistingArchiveDirect() Assert.IsTrue(testFile.TestArchive(true)); } - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { Assert.IsTrue(testFile.TestArchive(true)); testFile.IsStreamOwner = true; @@ -802,7 +866,6 @@ public void UnicodeNames() f.CommitUpdate(); Assert.IsTrue(f.TestArchive(true)); - } memStream.Seek(0, SeekOrigin.Begin); using (var zf = new ZipFile(memStream)) @@ -815,14 +878,14 @@ public void UnicodeNames() var entry = zf[index]; using (var entryStream = zf.GetInputStream(entry)) - using(var sr= new StreamReader(entryStream)) + using (var sr = new StreamReader(entryStream)) { content = sr.ReadToEnd(); } - //var content = + //var content = - Console.WriteLine($"Entry #{index}: {name}, Content: {content}"); + Console.WriteLine($"Entry #{index}: {name}, Content: {content}"); Assert.IsTrue(index >= 0); Assert.AreEqual(name, entry.Name); @@ -837,7 +900,8 @@ public void UpdateCommentOnlyInMemory() { var ms = new MemoryStream(); - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { testFile.IsStreamOwner = false; testFile.BeginUpdate(); testFile.Add(new StringMemoryDataSource("Aha"), "No1", CompressionMethod.Stored); @@ -848,7 +912,8 @@ public void UpdateCommentOnlyInMemory() Assert.IsTrue(testFile.TestArchive(true)); } - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { Assert.IsTrue(testFile.TestArchive(true)); Assert.AreEqual("", testFile.ZipFileComment); testFile.IsStreamOwner = false; @@ -860,7 +925,8 @@ public void UpdateCommentOnlyInMemory() Assert.IsTrue(testFile.TestArchive(true)); } - using (ZipFile testFile = new ZipFile(ms)) { + using (ZipFile testFile = new ZipFile(ms)) + { Assert.IsTrue(testFile.TestArchive(true)); Assert.AreEqual("Here is my comment", testFile.ZipFileComment); } @@ -875,11 +941,13 @@ public void UpdateCommentOnlyOnDisk() Assert.IsNotNull(tempFile, "No permission to execute this test?"); tempFile = Path.Combine(tempFile, "SharpZipTest.Zip"); - if (File.Exists(tempFile)) { + if (File.Exists(tempFile)) + { File.Delete(tempFile); } - using (ZipFile testFile = ZipFile.Create(tempFile)) { + using (ZipFile testFile = ZipFile.Create(tempFile)) + { testFile.BeginUpdate(); testFile.Add(new StringMemoryDataSource("Aha"), "No1", CompressionMethod.Stored); testFile.Add(new StringMemoryDataSource("And so it goes"), "No2", CompressionMethod.Stored); @@ -889,7 +957,8 @@ public void UpdateCommentOnlyOnDisk() Assert.IsTrue(testFile.TestArchive(true)); } - using (ZipFile testFile = new ZipFile(tempFile)) { + using (ZipFile testFile = new ZipFile(tempFile)) + { Assert.IsTrue(testFile.TestArchive(true)); Assert.AreEqual("", testFile.ZipFileComment); @@ -900,14 +969,16 @@ public void UpdateCommentOnlyOnDisk() Assert.IsTrue(testFile.TestArchive(true)); } - using (ZipFile testFile = new ZipFile(tempFile)) { + using (ZipFile testFile = new ZipFile(tempFile)) + { Assert.IsTrue(testFile.TestArchive(true)); Assert.AreEqual("Here is my comment", testFile.ZipFileComment); } File.Delete(tempFile); // Variant using indirect updating. - using (ZipFile testFile = ZipFile.Create(tempFile)) { + using (ZipFile testFile = ZipFile.Create(tempFile)) + { testFile.BeginUpdate(); testFile.Add(new StringMemoryDataSource("Aha"), "No1", CompressionMethod.Stored); testFile.Add(new StringMemoryDataSource("And so it goes"), "No2", CompressionMethod.Stored); @@ -917,7 +988,8 @@ public void UpdateCommentOnlyOnDisk() Assert.IsTrue(testFile.TestArchive(true)); } - using (ZipFile testFile = new ZipFile(tempFile)) { + using (ZipFile testFile = new ZipFile(tempFile)) + { Assert.IsTrue(testFile.TestArchive(true)); Assert.AreEqual("", testFile.ZipFileComment); @@ -928,7 +1000,8 @@ public void UpdateCommentOnlyOnDisk() Assert.IsTrue(testFile.TestArchive(true)); } - using (ZipFile testFile = new ZipFile(tempFile)) { + using (ZipFile testFile = new ZipFile(tempFile)) + { Assert.IsTrue(testFile.TestArchive(true)); Assert.AreEqual("Here is my comment", testFile.ZipFileComment); } @@ -941,7 +1014,8 @@ public void NameFactory() { var memStream = new MemoryStream(); var fixedTime = new DateTime(1981, 4, 3); - using (ZipFile f = new ZipFile(memStream)) { + using (ZipFile f = new ZipFile(memStream)) + { f.IsStreamOwner = false; ((ZipEntryFactory)f.EntryFactory).IsUnicodeText = true; ((ZipEntryFactory)f.EntryFactory).Setting = ZipEntryFactory.TimeSetting.Fixed; @@ -955,14 +1029,16 @@ public void NameFactory() "\u0680\u0685" // Arabic }; - foreach (string name in names) { + foreach (string name in names) + { f.Add(new StringMemoryDataSource("Hello world"), name, CompressionMethod.Deflated, true); } f.CommitUpdate(); Assert.IsTrue(f.TestArchive(true)); - foreach (string name in names) { + foreach (string name in names) + { int index = f.FindEntry(name, true); Assert.IsTrue(index >= 0); @@ -980,7 +1056,8 @@ public void NameFactory() public void NestedArchive() { var ms = new MemoryStream(); - using (ZipOutputStream zos = new ZipOutputStream(ms)) { + using (ZipOutputStream zos = new ZipOutputStream(ms)) + { zos.IsStreamOwner = false; var ze = new ZipEntry("Nest1"); @@ -992,7 +1069,8 @@ public void NestedArchive() byte[] data = ms.ToArray(); ms = new MemoryStream(); - using (ZipOutputStream zos = new ZipOutputStream(ms)) { + using (ZipOutputStream zos = new ZipOutputStream(ms)) + { zos.IsStreamOwner = false; var ze = new ZipEntry("Container"); ze.CompressionMethod = CompressionMethod.Stored; @@ -1000,11 +1078,13 @@ public void NestedArchive() zos.Write(data, 0, data.Length); } - using (ZipFile zipFile = new ZipFile(ms)) { + using (ZipFile zipFile = new ZipFile(ms)) + { ZipEntry e = zipFile[0]; Assert.AreEqual("Container", e.Name); - using (ZipFile nested = new ZipFile(zipFile.GetInputStream(0))) { + using (ZipFile nested = new ZipFile(zipFile.GetInputStream(0))) + { Assert.IsTrue(nested.TestArchive(true)); Assert.AreEqual(1, nested.Count); @@ -1019,10 +1099,11 @@ public void NestedArchive() } } - Stream GetPartialStream() + private Stream GetPartialStream() { var ms = new MemoryStream(); - using (ZipOutputStream zos = new ZipOutputStream(ms)) { + using (ZipOutputStream zos = new ZipOutputStream(ms)) + { zos.IsStreamOwner = false; var ze = new ZipEntry("E1"); diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipNameTransformHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipNameTransformHandling.cs index 2536494cd..634b9a0ab 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipNameTransformHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipNameTransformHandling.cs @@ -1,8 +1,8 @@ -using System; -using System.IO; -using ICSharpCode.SharpZipLib.Core; +using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; +using System; +using System.IO; namespace ICSharpCode.SharpZipLib.Tests.Zip { @@ -36,10 +36,13 @@ public void TooLong() { var zt = new ZipNameTransform(); var veryLong = new string('x', 65536); - try { + try + { zt.TransformDirectory(veryLong); Assert.Fail("Expected an exception"); - } catch (PathTooLongException) { + } + catch (PathTooLongException) + { } } @@ -48,9 +51,12 @@ public void LengthBoundaryOk() { var zt = new ZipNameTransform(); string veryLong = "c:\\" + new string('x', 65535); - try { + try + { zt.TransformDirectory(veryLong); - } catch { + } + catch + { Assert.Fail("Expected no exception"); } } diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipTests.cs index 2f5f9fcb2..eff2e007b 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipTests.cs @@ -1,16 +1,16 @@ -using System; -using System.IO; -using System.Security; -using System.Text; using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Tests.TestSupport; using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; +using System; +using System.IO; +using System.Security; +using System.Text; namespace ICSharpCode.SharpZipLib.Tests.Zip { - class RuntimeInfo + internal class RuntimeInfo { public RuntimeInfo(CompressionMethod method, int compressionLevel, int size, string password, bool getCrc) @@ -22,23 +22,27 @@ public RuntimeInfo(CompressionMethod method, int compressionLevel, this.random = false; original = new byte[Size]; - if (random) { + if (random) + { var rnd = new Random(); rnd.NextBytes(original); - } else { - for (int i = 0; i < size; ++i) { + } + else + { + for (int i = 0; i < size; ++i) + { original[i] = (byte)'A'; } } - if (getCrc) { + if (getCrc) + { var crc32 = new Crc32(); crc32.Update(new ArraySegment(original, 0, size)); crc = crc32.Value; } } - public RuntimeInfo(string password, bool isDirectory) { this.method = CompressionMethod.Stored; @@ -50,53 +54,64 @@ public RuntimeInfo(string password, bool isDirectory) original = new byte[0]; } - public byte[] Original { + public byte[] Original + { get { return original; } } - public CompressionMethod Method { + public CompressionMethod Method + { get { return method; } } - public int CompressionLevel { + public int CompressionLevel + { get { return compressionLevel; } } - public int Size { + public int Size + { get { return size; } } - public string Password { + public string Password + { get { return password; } } - bool Random { + private bool Random + { get { return random; } } - public long Crc { + public long Crc + { get { return crc; } } - public bool IsDirectory { + public bool IsDirectory + { get { return isDirectory_; } } #region Instance Fields - readonly byte[] original; - readonly CompressionMethod method; - int compressionLevel; - int size; - string password; - bool random; - bool isDirectory_; - long crc = -1; - #endregion + + private readonly byte[] original; + private readonly CompressionMethod method; + private int compressionLevel; + private int size; + private string password; + private bool random; + private bool isDirectory_; + private long crc = -1; + + #endregion Instance Fields } - class MemoryDataSource : IStaticDataSource + internal class MemoryDataSource : IStaticDataSource { #region Constructors + /// /// Initialise a new instance. /// @@ -105,7 +120,8 @@ public MemoryDataSource(byte[] data) { data_ = data; } - #endregion + + #endregion Constructors #region IDataSource Members @@ -117,14 +133,17 @@ public Stream GetSource() { return new MemoryStream(data_); } - #endregion + + #endregion IDataSource Members #region Instance Fields - readonly byte[] data_; - #endregion + + private readonly byte[] data_; + + #endregion Instance Fields } - class StringMemoryDataSource : MemoryDataSource + internal class StringMemoryDataSource : MemoryDataSource { public StringMemoryDataSource(string data) : base(Encoding.ASCII.GetBytes(data)) @@ -137,9 +156,12 @@ public class ZipBase static protected string GetTempFilePath() { string result = null; - try { + try + { result = Path.GetTempPath(); - } catch (SecurityException) { + } + catch (SecurityException) + { } return result; } @@ -148,38 +170,49 @@ protected byte[] MakeInMemoryZip(bool withSeek, params object[] createSpecs) { MemoryStream ms; - if (withSeek) { + if (withSeek) + { ms = new MemoryStream(); - } else { + } + else + { ms = new MemoryStreamWithoutSeek(); } - using (ZipOutputStream outStream = new ZipOutputStream(ms)) { - for (int counter = 0; counter < createSpecs.Length; ++counter) { + using (ZipOutputStream outStream = new ZipOutputStream(ms)) + { + for (int counter = 0; counter < createSpecs.Length; ++counter) + { var info = createSpecs[counter] as RuntimeInfo; outStream.Password = info.Password; - if (info.Method != CompressionMethod.Stored) { + if (info.Method != CompressionMethod.Stored) + { outStream.SetLevel(info.CompressionLevel); // 0 - store only to 9 - means best compression } string entryName; - if (info.IsDirectory) { + if (info.IsDirectory) + { entryName = "dir" + counter + "/"; - } else { + } + else + { entryName = "entry" + counter + ".tst"; } var entry = new ZipEntry(entryName); entry.CompressionMethod = info.Method; - if (info.Crc >= 0) { + if (info.Crc >= 0) + { entry.Crc = info.Crc; } outStream.PutNextEntry(entry); - if (info.Size > 0) { + if (info.Size > 0) + { outStream.Write(info.Original, 0, info.Original.Length); } } @@ -192,16 +225,21 @@ protected byte[] MakeInMemoryZip(ref byte[] original, CompressionMethod method, { MemoryStream ms; - if (withSeek) { + if (withSeek) + { ms = new MemoryStream(); - } else { + } + else + { ms = new MemoryStreamWithoutSeek(); } - using (ZipOutputStream outStream = new ZipOutputStream(ms)) { + using (ZipOutputStream outStream = new ZipOutputStream(ms)) + { outStream.Password = password; - if (method != CompressionMethod.Stored) { + if (method != CompressionMethod.Stored) + { outStream.SetLevel(compressionLevel); // 0 - store only to 9 - means best compression } @@ -210,7 +248,8 @@ protected byte[] MakeInMemoryZip(ref byte[] original, CompressionMethod method, outStream.PutNextEntry(entry); - if (size > 0) { + if (size > 0) + { var rnd = new Random(); original = new byte[size]; rnd.NextBytes(original); @@ -219,7 +258,8 @@ protected byte[] MakeInMemoryZip(ref byte[] original, CompressionMethod method, // throws up buffering problems including with encryption the original // source for this change. int index = 0; - while (size > 0) { + while (size > 0) + { int count = (size > 0x200) ? 0x200 : size; outStream.Write(original, index, count); size -= 0x200; @@ -232,9 +272,11 @@ protected byte[] MakeInMemoryZip(ref byte[] original, CompressionMethod method, protected static void MakeTempFile(string name, int size) { - using (FileStream fs = File.Create(name)) { + using (FileStream fs = File.Create(name)) + { byte[] buffer = new byte[4096]; - while (size > 0) { + while (size > 0) + { fs.Write(buffer, 0, Math.Min(size, buffer.Length)); size -= buffer.Length; } @@ -246,19 +288,22 @@ protected static byte ScatterValue(byte rhs) return (byte)((rhs * 253 + 7) & 0xff); } - static void AddKnownDataToEntry(ZipOutputStream zipStream, int size) + private static void AddKnownDataToEntry(ZipOutputStream zipStream, int size) { - if (size > 0) { + if (size > 0) + { byte nextValue = 0; int bufferSize = Math.Min(size, 65536); byte[] data = new byte[bufferSize]; int currentIndex = 0; - for (int i = 0; i < size; ++i) { + for (int i = 0; i < size; ++i) + { data[currentIndex] = nextValue; nextValue = ScatterValue(nextValue); currentIndex += 1; - if ((currentIndex >= data.Length) || (i + 1 == size)) { + if ((currentIndex >= data.Length) || (i + 1 == size)) + { zipStream.Write(data, 0, currentIndex); currentIndex = 0; } @@ -268,18 +313,22 @@ static void AddKnownDataToEntry(ZipOutputStream zipStream, int size) public void WriteToFile(string fileName, byte[] data) { - using (FileStream fs = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { + using (FileStream fs = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) + { fs.Write(data, 0, data.Length); } } #region MakeZipFile + protected void MakeZipFile(Stream storage, bool isOwner, string[] names, int size, string comment) { - using (ZipOutputStream zOut = new ZipOutputStream(storage)) { + using (ZipOutputStream zOut = new ZipOutputStream(storage)) + { zOut.IsStreamOwner = isOwner; zOut.SetComment(comment); - for (int i = 0; i < names.Length; ++i) { + for (int i = 0; i < names.Length; ++i) + { zOut.PutNextEntry(new ZipEntry(names[i])); AddKnownDataToEntry(zOut, size); } @@ -289,10 +338,13 @@ protected void MakeZipFile(Stream storage, bool isOwner, string[] names, int siz protected void MakeZipFile(string name, string[] names, int size, string comment) { - using (FileStream fs = File.Create(name)) { - using (ZipOutputStream zOut = new ZipOutputStream(fs)) { + using (FileStream fs = File.Create(name)) + { + using (ZipOutputStream zOut = new ZipOutputStream(fs)) + { zOut.SetComment(comment); - for (int i = 0; i < names.Length; ++i) { + for (int i = 0; i < names.Length; ++i) + { zOut.PutNextEntry(new ZipEntry(names[i])); AddKnownDataToEntry(zOut, size); } @@ -301,15 +353,19 @@ protected void MakeZipFile(string name, string[] names, int size, string comment fs.Close(); } } - #endregion + + #endregion MakeZipFile #region MakeZipFile Entries + protected void MakeZipFile(string name, string entryNamePrefix, int entries, int size, string comment) { using (FileStream fs = File.Create(name)) - using (ZipOutputStream zOut = new ZipOutputStream(fs)) { + using (ZipOutputStream zOut = new ZipOutputStream(fs)) + { zOut.SetComment(comment); - for (int i = 0; i < entries; ++i) { + for (int i = 0; i < entries; ++i) + { zOut.PutNextEntry(new ZipEntry(entryNamePrefix + (i + 1))); AddKnownDataToEntry(zOut, size); } @@ -319,17 +375,19 @@ protected void MakeZipFile(string name, string entryNamePrefix, int entries, int protected void MakeZipFile(Stream storage, bool isOwner, string entryNamePrefix, int entries, int size, string comment) { - using (ZipOutputStream zOut = new ZipOutputStream(storage)) { + using (ZipOutputStream zOut = new ZipOutputStream(storage)) + { zOut.IsStreamOwner = isOwner; zOut.SetComment(comment); - for (int i = 0; i < entries; ++i) { + for (int i = 0; i < entries; ++i) + { zOut.PutNextEntry(new ZipEntry(entryNamePrefix + (i + 1))); AddKnownDataToEntry(zOut, size); } } } - #endregion + #endregion MakeZipFile Entries protected static void CheckKnownEntry(Stream inStream, int expectedCount) { @@ -338,9 +396,11 @@ protected static void CheckKnownEntry(Stream inStream, int expectedCount) int bytesRead; int total = 0; byte nextValue = 0; - while ((bytesRead = inStream.Read(buffer, 0, buffer.Length)) > 0) { + while ((bytesRead = inStream.Read(buffer, 0, buffer.Length)) > 0) + { total += bytesRead; - for (int i = 0; i < bytesRead; ++i) { + for (int i = 0; i < bytesRead; ++i) + { Assert.AreEqual(nextValue, buffer[i], "Wrong value read from entry"); nextValue = ScatterValue(nextValue); } @@ -368,15 +428,15 @@ protected long ReadLong(Stream stream) long result = ReadInt(stream) & 0xffffffff; return result | (((long)ReadInt(stream)) << 32); } - } - class TestHelper + internal class TestHelper { static public void SaveMemoryStream(MemoryStream ms, string fileName) { byte[] data = ms.ToArray(); - using (FileStream fs = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { + using (FileStream fs = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) + { fs.Write(data, 0, data.Length); } } @@ -386,15 +446,20 @@ static public int CompareDosDateTimes(DateTime l, DateTime r) // Compare dates to dos accuracy... // Ticks can be different yet all these values are still the same! int result = l.Year - r.Year; - if (result == 0) { + if (result == 0) + { result = l.Month - r.Month; - if (result == 0) { + if (result == 0) + { result = l.Day - r.Day; - if (result == 0) { + if (result == 0) + { result = l.Hour - r.Hour; - if (result == 0) { + if (result == 0) + { result = l.Minute - r.Minute; - if (result == 0) { + if (result == 0) + { result = (l.Second / 2) - (r.Second / 2); } }