Summary

Class:ICSharpCode.SharpZipLib.Core.StreamUtils
Assembly:ICSharpCode.SharpZipLib
File(s):C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Core\StreamUtils.cs
Covered lines:25
Uncovered lines:53
Coverable lines:78
Total lines:208
Line coverage:32%
Branch coverage:34%

Metrics

MethodCyclomatic ComplexitySequence CoverageBranch Coverage
ReadFully(...)1100100
ReadFully(...)966.6758.82
Copy(...)776.4769.23
Copy(...)100
Copy(...)1200
.ctor()100

File(s)

C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Core\StreamUtils.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3
 4namespace ICSharpCode.SharpZipLib.Core
 5{
 6  /// <summary>
 7  /// Provides simple <see cref="Stream"/>" utilities.
 8  /// </summary>
 9  public sealed class StreamUtils
 10  {
 11    /// <summary>
 12    /// Read from a <see cref="Stream"/> ensuring all the required data is read.
 13    /// </summary>
 14    /// <param name="stream">The stream to read.</param>
 15    /// <param name="buffer">The buffer to fill.</param>
 16    /// <seealso cref="ReadFully(Stream,byte[],int,int)"/>
 17    static public void ReadFully(Stream stream, byte[] buffer)
 18    {
 26378919      ReadFully(stream, buffer, 0, buffer.Length);
 26378920    }
 21
 22    /// <summary>
 23    /// Read from a <see cref="Stream"/>" ensuring all the required data is read.
 24    /// </summary>
 25    /// <param name="stream">The stream to read data from.</param>
 26    /// <param name="buffer">The buffer to store data in.</param>
 27    /// <param name="offset">The offset at which to begin storing data.</param>
 28    /// <param name="count">The number of bytes of data to store.</param>
 29    /// <exception cref="ArgumentNullException">Required parameter is null</exception>
 30    /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> and or <paramref name="count"/> are inva
 31    /// <exception cref="EndOfStreamException">End of stream is encountered before all the data has been read.</exceptio
 32    static public void ReadFully(Stream stream, byte[] buffer, int offset, int count)
 33    {
 32974534       if (stream == null) {
 035        throw new ArgumentNullException(nameof(stream));
 36      }
 37
 32974538       if (buffer == null) {
 039        throw new ArgumentNullException(nameof(buffer));
 40      }
 41
 42      // Offset can equal length when buffer and count are 0.
 32974543       if ((offset < 0) || (offset > buffer.Length)) {
 044        throw new ArgumentOutOfRangeException(nameof(offset));
 45      }
 46
 32974547       if ((count < 0) || (offset + count > buffer.Length)) {
 048        throw new ArgumentOutOfRangeException(nameof(count));
 49      }
 50
 52767851       while (count > 0) {
 19793352        int readCount = stream.Read(buffer, offset, count);
 19793353         if (readCount <= 0) {
 054          throw new EndOfStreamException();
 55        }
 19793356        offset += readCount;
 19793357        count -= readCount;
 58      }
 32974559    }
 60
 61    /// <summary>
 62    /// Copy the contents of one <see cref="Stream"/> to another.
 63    /// </summary>
 64    /// <param name="source">The stream to source data from.</param>
 65    /// <param name="destination">The stream to write data to.</param>
 66    /// <param name="buffer">The buffer to use during copying.</param>
 67    static public void Copy(Stream source, Stream destination, byte[] buffer)
 68    {
 869       if (source == null) {
 070        throw new ArgumentNullException(nameof(source));
 71      }
 72
 873       if (destination == null) {
 074        throw new ArgumentNullException(nameof(destination));
 75      }
 76
 877       if (buffer == null) {
 078        throw new ArgumentNullException(nameof(buffer));
 79      }
 80
 81      // Ensure a reasonable size of buffer is used without being prohibitive.
 882       if (buffer.Length < 128) {
 083        throw new ArgumentException("Buffer is too small", nameof(buffer));
 84      }
 85
 886      bool copying = true;
 87
 2488       while (copying) {
 1689        int bytesRead = source.Read(buffer, 0, buffer.Length);
 1690         if (bytesRead > 0) {
 891          destination.Write(buffer, 0, bytesRead);
 892        } else {
 893          destination.Flush();
 894          copying = false;
 95        }
 96      }
 897    }
 98
 99    /// <summary>
 100    /// Copy the contents of one <see cref="Stream"/> to another.
 101    /// </summary>
 102    /// <param name="source">The stream to source data from.</param>
 103    /// <param name="destination">The stream to write data to.</param>
 104    /// <param name="buffer">The buffer to use during copying.</param>
 105    /// <param name="progressHandler">The <see cref="ProgressHandler">progress handler delegate</see> to use.</param>
 106    /// <param name="updateInterval">The minimum <see cref="TimeSpan"/> between progress updates.</param>
 107    /// <param name="sender">The source for this event.</param>
 108    /// <param name="name">The name to use with the event.</param>
 109    /// <remarks>This form is specialised for use within #Zip to support events during archive operations.</remarks>
 110    static public void Copy(Stream source, Stream destination,
 111      byte[] buffer, ProgressHandler progressHandler, TimeSpan updateInterval, object sender, string name)
 112    {
 0113      Copy(source, destination, buffer, progressHandler, updateInterval, sender, name, -1);
 0114    }
 115
 116    /// <summary>
 117    /// Copy the contents of one <see cref="Stream"/> to another.
 118    /// </summary>
 119    /// <param name="source">The stream to source data from.</param>
 120    /// <param name="destination">The stream to write data to.</param>
 121    /// <param name="buffer">The buffer to use during copying.</param>
 122    /// <param name="progressHandler">The <see cref="ProgressHandler">progress handler delegate</see> to use.</param>
 123    /// <param name="updateInterval">The minimum <see cref="TimeSpan"/> between progress updates.</param>
 124    /// <param name="sender">The source for this event.</param>
 125    /// <param name="name">The name to use with the event.</param>
 126    /// <param name="fixedTarget">A predetermined fixed target value to use with progress updates.
 127    /// If the value is negative the target is calculated by looking at the stream.</param>
 128    /// <remarks>This form is specialised for use within #Zip to support events during archive operations.</remarks>
 129    static public void Copy(Stream source, Stream destination,
 130      byte[] buffer,
 131      ProgressHandler progressHandler, TimeSpan updateInterval,
 132      object sender, string name, long fixedTarget)
 133    {
 0134       if (source == null) {
 0135        throw new ArgumentNullException(nameof(source));
 136      }
 137
 0138       if (destination == null) {
 0139        throw new ArgumentNullException(nameof(destination));
 140      }
 141
 0142       if (buffer == null) {
 0143        throw new ArgumentNullException(nameof(buffer));
 144      }
 145
 146      // Ensure a reasonable size of buffer is used without being prohibitive.
 0147       if (buffer.Length < 128) {
 0148        throw new ArgumentException("Buffer is too small", nameof(buffer));
 149      }
 150
 0151       if (progressHandler == null) {
 0152        throw new ArgumentNullException(nameof(progressHandler));
 153      }
 154
 0155      bool copying = true;
 156
 0157      DateTime marker = DateTime.Now;
 0158      long processed = 0;
 0159      long target = 0;
 160
 0161       if (fixedTarget >= 0) {
 0162        target = fixedTarget;
 0163       } else if (source.CanSeek) {
 0164        target = source.Length - source.Position;
 165      }
 166
 167      // Always fire 0% progress..
 0168      var args = new ProgressEventArgs(name, processed, target);
 0169      progressHandler(sender, args);
 170
 0171      bool progressFired = true;
 172
 0173       while (copying) {
 0174        int bytesRead = source.Read(buffer, 0, buffer.Length);
 0175         if (bytesRead > 0) {
 0176          processed += bytesRead;
 0177          progressFired = false;
 0178          destination.Write(buffer, 0, bytesRead);
 0179        } else {
 0180          destination.Flush();
 0181          copying = false;
 182        }
 183
 0184         if (DateTime.Now - marker > updateInterval) {
 0185          progressFired = true;
 0186          marker = DateTime.Now;
 0187          args = new ProgressEventArgs(name, processed, target);
 0188          progressHandler(sender, args);
 189
 0190          copying = args.ContinueRunning;
 191        }
 192      }
 193
 0194       if (!progressFired) {
 0195        args = new ProgressEventArgs(name, processed, target);
 0196        progressHandler(sender, args);
 197      }
 0198    }
 199
 200    /// <summary>
 201    /// Initialise an instance of <see cref="StreamUtils"></see>
 202    /// </summary>
 0203    private StreamUtils()
 204    {
 205      // Do nothing.
 0206    }
 207  }
 208}