# ICSharpCode.SharpZipLib.Core.StreamUtils - Coverage Report

# 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

Method | Cyclomatic Complexity | Sequence Coverage | Branch Coverage
--- | --- | --- | ---
ReadFully(...) | 1 | 100 | 100
ReadFully(...) | 9 | 66.67 | 58.82
Copy(...) | 7 | 76.47 | 69.23
Copy(...) | 1 | 0 | 0
Copy(...) | 12 | 0 | 0
.ctor() | 1 | 0 | 0

# File(s)

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

| # | Line |  | Line coverage
--- | --- | --- | --- | ---
|  | `1` |  | `using System;`
|  | `2` |  | `using System.IO;`
|  | `3` |  | ``
|  | `4` |  | `namespace 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` |  | `{`
| 263789 | `19` |  | `ReadFully(stream, buffer, 0, buffer.Length);`
| 263789 | `20` |  | `}`
|  | `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` |  | `{`
| 329745 | `34` |  | `if (stream == null) {`
| 0 | `35` |  | `throw new ArgumentNullException(nameof(stream));`
|  | `36` |  | `}`
|  | `37` |  | ``
| 329745 | `38` |  | `if (buffer == null) {`
| 0 | `39` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `40` |  | `}`
|  | `41` |  | ``
|  | `42` |  | `// Offset can equal length when buffer and count are 0.`
| 329745 | `43` |  | `if ((offset < 0) || (offset > buffer.Length)) {`
| 0 | `44` |  | `throw new ArgumentOutOfRangeException(nameof(offset));`
|  | `45` |  | `}`
|  | `46` |  | ``
| 329745 | `47` |  | `if ((count < 0) || (offset + count > buffer.Length)) {`
| 0 | `48` |  | `throw new ArgumentOutOfRangeException(nameof(count));`
|  | `49` |  | `}`
|  | `50` |  | ``
| 527678 | `51` |  | `while (count > 0) {`
| 197933 | `52` |  | `int readCount = stream.Read(buffer, offset, count);`
| 197933 | `53` |  | `if (readCount <= 0) {`
| 0 | `54` |  | `throw new EndOfStreamException();`
|  | `55` |  | `}`
| 197933 | `56` |  | `offset += readCount;`
| 197933 | `57` |  | `count -= readCount;`
|  | `58` |  | `}`
| 329745 | `59` |  | `}`
|  | `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` |  | `{`
| 8 | `69` |  | `if (source == null) {`
| 0 | `70` |  | `throw new ArgumentNullException(nameof(source));`
|  | `71` |  | `}`
|  | `72` |  | ``
| 8 | `73` |  | `if (destination == null) {`
| 0 | `74` |  | `throw new ArgumentNullException(nameof(destination));`
|  | `75` |  | `}`
|  | `76` |  | ``
| 8 | `77` |  | `if (buffer == null) {`
| 0 | `78` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `79` |  | `}`
|  | `80` |  | ``
|  | `81` |  | `// Ensure a reasonable size of buffer is used without being prohibitive.`
| 8 | `82` |  | `if (buffer.Length < 128) {`
| 0 | `83` |  | `throw new ArgumentException("Buffer is too small", nameof(buffer));`
|  | `84` |  | `}`
|  | `85` |  | ``
| 8 | `86` |  | `bool copying = true;`
|  | `87` |  | ``
| 24 | `88` |  | `while (copying) {`
| 16 | `89` |  | `int bytesRead = source.Read(buffer, 0, buffer.Length);`
| 16 | `90` |  | `if (bytesRead > 0) {`
| 8 | `91` |  | `destination.Write(buffer, 0, bytesRead);`
| 8 | `92` |  | `} else {`
| 8 | `93` |  | `destination.Flush();`
| 8 | `94` |  | `copying = false;`
|  | `95` |  | `}`
|  | `96` |  | `}`
| 8 | `97` |  | `}`
|  | `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` |  | `{`
| 0 | `113` |  | `Copy(source, destination, buffer, progressHandler, updateInterval, sender, name, -1);`
| 0 | `114` |  | `}`
|  | `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` |  | `{`
| 0 | `134` |  | `if (source == null) {`
| 0 | `135` |  | `throw new ArgumentNullException(nameof(source));`
|  | `136` |  | `}`
|  | `137` |  | ``
| 0 | `138` |  | `if (destination == null) {`
| 0 | `139` |  | `throw new ArgumentNullException(nameof(destination));`
|  | `140` |  | `}`
|  | `141` |  | ``
| 0 | `142` |  | `if (buffer == null) {`
| 0 | `143` |  | `throw new ArgumentNullException(nameof(buffer));`
|  | `144` |  | `}`
|  | `145` |  | ``
|  | `146` |  | `// Ensure a reasonable size of buffer is used without being prohibitive.`
| 0 | `147` |  | `if (buffer.Length < 128) {`
| 0 | `148` |  | `throw new ArgumentException("Buffer is too small", nameof(buffer));`
|  | `149` |  | `}`
|  | `150` |  | ``
| 0 | `151` |  | `if (progressHandler == null) {`
| 0 | `152` |  | `throw new ArgumentNullException(nameof(progressHandler));`
|  | `153` |  | `}`
|  | `154` |  | ``
| 0 | `155` |  | `bool copying = true;`
|  | `156` |  | ``
| 0 | `157` |  | `DateTime marker = DateTime.Now;`
| 0 | `158` |  | `long processed = 0;`
| 0 | `159` |  | `long target = 0;`
|  | `160` |  | ``
| 0 | `161` |  | `if (fixedTarget >= 0) {`
| 0 | `162` |  | `target = fixedTarget;`
| 0 | `163` |  | `} else if (source.CanSeek) {`
| 0 | `164` |  | `target = source.Length - source.Position;`
|  | `165` |  | `}`
|  | `166` |  | ``
|  | `167` |  | `// Always fire 0% progress..`
| 0 | `168` |  | `var args = new ProgressEventArgs(name, processed, target);`
| 0 | `169` |  | `progressHandler(sender, args);`
|  | `170` |  | ``
| 0 | `171` |  | `bool progressFired = true;`
|  | `172` |  | ``
| 0 | `173` |  | `while (copying) {`
| 0 | `174` |  | `int bytesRead = source.Read(buffer, 0, buffer.Length);`
| 0 | `175` |  | `if (bytesRead > 0) {`
| 0 | `176` |  | `processed += bytesRead;`
| 0 | `177` |  | `progressFired = false;`
| 0 | `178` |  | `destination.Write(buffer, 0, bytesRead);`
| 0 | `179` |  | `} else {`
| 0 | `180` |  | `destination.Flush();`
| 0 | `181` |  | `copying = false;`
|  | `182` |  | `}`
|  | `183` |  | ``
| 0 | `184` |  | `if (DateTime.Now - marker > updateInterval) {`
| 0 | `185` |  | `progressFired = true;`
| 0 | `186` |  | `marker = DateTime.Now;`
| 0 | `187` |  | `args = new ProgressEventArgs(name, processed, target);`
| 0 | `188` |  | `progressHandler(sender, args);`
|  | `189` |  | ``
| 0 | `190` |  | `copying = args.ContinueRunning;`
|  | `191` |  | `}`
|  | `192` |  | `}`
|  | `193` |  | ``
| 0 | `194` |  | `if (!progressFired) {`
| 0 | `195` |  | `args = new ProgressEventArgs(name, processed, target);`
| 0 | `196` |  | `progressHandler(sender, args);`
|  | `197` |  | `}`
| 0 | `198` |  | `}`
|  | `199` |  | ``
|  | `200` |  | `/// <summary>`
|  | `201` |  | `/// Initialise an instance of <see cref="StreamUtils"></see>`
|  | `202` |  | `/// </summary>`
| 0 | `203` |  | `private StreamUtils()`
|  | `204` |  | `{`
|  | `205` |  | `// Do nothing.`
| 0 | `206` |  | `}`
|  | `207` |  | `}`
|  | `208` |  | `}`