Summary

Class:ICSharpCode.SharpZipLib.Zip.Compression.Streams.OutputWindow
Assembly:ICSharpCode.SharpZipLib
File(s):C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Zip\Compression\Streams\OutputWindow.cs
Covered lines:46
Uncovered lines:20
Coverable lines:66
Total lines:195
Line coverage:69.6%
Branch coverage:53.3%

Metrics

MethodCyclomatic ComplexitySequence CoverageBranch Coverage
Write(...)28066.67
SlowRepeat(...)200
Repeat(...)678.5772.73
CopyStored(...)310080
CopyDict(...)400
GetFreeSpace()1100100
GetAvailable()1100100
CopyOutput(...)493.7585.71
Reset()1100100
.ctor()1100100

File(s)

C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Zip\Compression\Streams\OutputWindow.cs

#LineLine coverage
 1using System;
 2
 3namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams
 4{
 5  /// <summary>
 6  /// Contains the output from the Inflation process.
 7  /// We need to have a window so that we can refer backwards into the output stream
 8  /// to repeat stuff.<br/>
 9  /// Author of the original java version : John Leuner
 10  /// </summary>
 11  public class OutputWindow
 12  {
 13    #region Constants
 14    const int WindowSize = 1 << 15;
 15    const int WindowMask = WindowSize - 1;
 16    #endregion
 17
 18    #region Instance Fields
 43519    byte[] window = new byte[WindowSize]; //The window is 2^15 bytes
 20    int windowEnd;
 21    int windowFilled;
 22    #endregion
 23
 24    /// <summary>
 25    /// Write a byte to this output window
 26    /// </summary>
 27    /// <param name="value">value to write</param>
 28    /// <exception cref="InvalidOperationException">
 29    /// if window is full
 30    /// </exception>
 31    public void Write(int value)
 32    {
 922933       if (windowFilled++ == WindowSize) {
 034        throw new InvalidOperationException("Window full");
 35      }
 922936      window[windowEnd++] = (byte)value;
 922937      windowEnd &= WindowMask;
 922938    }
 39
 40
 41    private void SlowRepeat(int repStart, int length, int distance)
 42    {
 043       while (length-- > 0) {
 044        window[windowEnd++] = window[repStart++];
 045        windowEnd &= WindowMask;
 046        repStart &= WindowMask;
 47      }
 048    }
 49
 50    /// <summary>
 51    /// Append a byte pattern already in the window itself
 52    /// </summary>
 53    /// <param name="length">length of pattern to copy</param>
 54    /// <param name="distance">distance from end of window pattern occurs</param>
 55    /// <exception cref="InvalidOperationException">
 56    /// If the repeated data overflows the window
 57    /// </exception>
 58    public void Repeat(int length, int distance)
 59    {
 9760       if ((windowFilled += length) > WindowSize) {
 061        throw new InvalidOperationException("Window full");
 62      }
 63
 9764      int repStart = (windowEnd - distance) & WindowMask;
 9765      int border = WindowSize - length;
 9766       if ((repStart <= border) && (windowEnd < border)) {
 9767         if (length <= distance) {
 3768          System.Array.Copy(window, repStart, window, windowEnd, length);
 3769          windowEnd += length;
 3770        } else {
 71          // We have to copy manually, since the repeat pattern overlaps.
 1146172           while (length-- > 0) {
 1140173            window[windowEnd++] = window[repStart++];
 74          }
 75        }
 6076      } else {
 077        SlowRepeat(repStart, length, distance);
 78      }
 079    }
 80
 81    /// <summary>
 82    /// Copy from input manipulator to internal window
 83    /// </summary>
 84    /// <param name="input">source of data</param>
 85    /// <param name="length">length of data to copy</param>
 86    /// <returns>the number of bytes copied</returns>
 87    public int CopyStored(StreamManipulator input, int length)
 88    {
 228089      length = Math.Min(Math.Min(length, WindowSize - windowFilled), input.AvailableBytes);
 90      int copied;
 91
 228092      int tailLen = WindowSize - windowEnd;
 228093       if (length > tailLen) {
 9694        copied = input.CopyBytes(window, windowEnd, tailLen);
 9695         if (copied == tailLen) {
 9696          copied += input.CopyBytes(window, 0, length - tailLen);
 97        }
 9698      } else {
 218499        copied = input.CopyBytes(window, windowEnd, length);
 100      }
 101
 2280102      windowEnd = (windowEnd + copied) & WindowMask;
 2280103      windowFilled += copied;
 2280104      return copied;
 105    }
 106
 107    /// <summary>
 108    /// Copy dictionary to window
 109    /// </summary>
 110    /// <param name="dictionary">source dictionary</param>
 111    /// <param name="offset">offset of start in source dictionary</param>
 112    /// <param name="length">length of dictionary</param>
 113    /// <exception cref="InvalidOperationException">
 114    /// If window isnt empty
 115    /// </exception>
 116    public void CopyDict(byte[] dictionary, int offset, int length)
 117    {
 0118       if (dictionary == null) {
 0119        throw new ArgumentNullException(nameof(dictionary));
 120      }
 121
 0122       if (windowFilled > 0) {
 0123        throw new InvalidOperationException();
 124      }
 125
 0126       if (length > WindowSize) {
 0127        offset += length - WindowSize;
 0128        length = WindowSize;
 129      }
 0130      System.Array.Copy(dictionary, offset, window, 0, length);
 0131      windowEnd = length & WindowMask;
 0132    }
 133
 134    /// <summary>
 135    /// Get remaining unfilled space in window
 136    /// </summary>
 137    /// <returns>Number of bytes left in window</returns>
 138    public int GetFreeSpace()
 139    {
 371140      return WindowSize - windowFilled;
 141    }
 142
 143    /// <summary>
 144    /// Get bytes available for output in window
 145    /// </summary>
 146    /// <returns>Number of bytes filled</returns>
 147    public int GetAvailable()
 148    {
 3783149      return windowFilled;
 150    }
 151
 152    /// <summary>
 153    /// Copy contents of window to output
 154    /// </summary>
 155    /// <param name="output">buffer to copy to</param>
 156    /// <param name="offset">offset to start at</param>
 157    /// <param name="len">number of bytes to count</param>
 158    /// <returns>The number of bytes copied</returns>
 159    /// <exception cref="InvalidOperationException">
 160    /// If a window underflow occurs
 161    /// </exception>
 162    public int CopyOutput(byte[] output, int offset, int len)
 163    {
 4523164      int copyEnd = windowEnd;
 4523165       if (len > windowFilled) {
 4401166        len = windowFilled;
 4401167      } else {
 122168        copyEnd = (windowEnd - windowFilled + len) & WindowMask;
 169      }
 170
 4523171      int copied = len;
 4523172      int tailLen = len - copyEnd;
 173
 4523174       if (tailLen > 0) {
 102175        System.Array.Copy(window, WindowSize - tailLen, output, offset, tailLen);
 102176        offset += tailLen;
 102177        len = copyEnd;
 178      }
 4523179      System.Array.Copy(window, copyEnd - len, output, offset, len);
 4523180      windowFilled -= copied;
 4523181       if (windowFilled < 0) {
 0182        throw new InvalidOperationException();
 183      }
 4523184      return copied;
 185    }
 186
 187    /// <summary>
 188    /// Reset by clearing window so <see cref="GetAvailable">GetAvailable</see> returns 0
 189    /// </summary>
 190    public void Reset()
 191    {
 41192      windowFilled = windowEnd = 0;
 41193    }
 194  }
 195}