Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Sys / System / IO / compression / OutputWindow.cs / 1 / OutputWindow.cs
namespace System.IO.Compression
{
using System;
using System.Diagnostics;
using System.Globalization;
// This class maintains a window for decompressed output.
// We need to keep this because the decompressed information can be
// a literal or a length/distance pair. For length/distance pair,
// we need to look back in the output window and copy bytes from there.
// We use a byte array of WindowSize circularly.
//
internal class OutputWindow {
private const int WindowSize = 32768;
private const int WindowMask = 32767;
private byte[] window = new byte[WindowSize]; //The window is 2^15 bytes
private int end; // this is the position to where we should write next byte
private int bytesUsed; // The number of bytes in the output window which is not consumed.
// Add a byte to output window
public void Write(byte b) {
Debug.WriteLineIf(CompressionTracingSwitch.Verbose, String.Format(CultureInfo.InvariantCulture, "Literal: {0}", b), "Compression");
Debug.Assert(bytesUsed < WindowSize, "Can't add byte when window is full!");
window[end++] = b;
end &= WindowMask;
++bytesUsed;
}
public void WriteLengthDistance(int length, int distance) {
Debug.WriteLineIf(CompressionTracingSwitch.Verbose, String.Format(CultureInfo.InvariantCulture, "Length/Distance: {0}:{1}", length, distance), "Compression");
Debug.Assert((bytesUsed + length) <= WindowSize, "No Enough space");
// move backwards distance bytes in the output stream,
// and copy length bytes from this position to the output stream.
bytesUsed += length;
int copyStart = (end - distance) & WindowMask; // start position for coping.
int border = WindowSize - length;
if (copyStart <= border && end < border) {
if (length <= distance) {
System.Array.Copy(window, copyStart, window, end, length);
end += length;
} else {
// The referenced string may overlap the current
// position; for example, if the last 2 bytes decoded have values
// X and Y, a string reference with
// adds X,Y,X,Y,X to the output stream.
while (length-- > 0) {
window[end++] = window[copyStart++];
}
}
}
else { // copy byte by byte
while (length-- > 0) {
window[end++] = window[copyStart++];
end &= WindowMask;
copyStart &= WindowMask;
}
}
}
// Copy up to length of bytes from input directly.
// This is used for uncompressed block.
public int CopyFrom(InputBuffer input, int length) {
length = Math.Min(Math.Min(length, WindowSize - bytesUsed), input.AvailableBytes);
int copied;
// We might need wrap around to copy all bytes.
int tailLen = WindowSize - end;
if (length > tailLen) {
// copy the first part
copied = input.CopyTo(window, end, tailLen);
if (copied == tailLen) {
// only try to copy the second part if we have enough bytes in input
copied += input.CopyTo(window, 0, length - tailLen);
}
}
else {
// only one copy is needed if there is no wrap around.
copied = input.CopyTo(window, end, length);
}
end = (end + copied) & WindowMask;
bytesUsed += copied;
return copied;
}
// Free space in output window
public int FreeBytes {
get {
return WindowSize - bytesUsed;
}
}
// bytes not consumed in output window
public int AvailableBytes {
get {
return bytesUsed;
}
}
// copy the decompressed bytes to output array.
public int CopyTo(byte[] output, int offset, int length) {
int copy_end;
if (length > bytesUsed) { // we can copy all the decompressed bytes out
copy_end = end;
length = bytesUsed;
} else {
copy_end = (end - bytesUsed + length) & WindowMask; // copy length of bytes
}
int copied = length;
int tailLen = length - copy_end;
if ( tailLen > 0) { // this means we need to copy two parts seperately
// copy tailLen bytes from the end of output window
System.Array.Copy(window, WindowSize - tailLen,
output, offset, tailLen);
offset += tailLen;
length = copy_end;
}
System.Array.Copy(window, copy_end - length, output, offset, length);
bytesUsed -= copied;
Debug.Assert(bytesUsed >= 0, "check this function and find why we copied more bytes than we have");
return copied;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace System.IO.Compression
{
using System;
using System.Diagnostics;
using System.Globalization;
// This class maintains a window for decompressed output.
// We need to keep this because the decompressed information can be
// a literal or a length/distance pair. For length/distance pair,
// we need to look back in the output window and copy bytes from there.
// We use a byte array of WindowSize circularly.
//
internal class OutputWindow {
private const int WindowSize = 32768;
private const int WindowMask = 32767;
private byte[] window = new byte[WindowSize]; //The window is 2^15 bytes
private int end; // this is the position to where we should write next byte
private int bytesUsed; // The number of bytes in the output window which is not consumed.
// Add a byte to output window
public void Write(byte b) {
Debug.WriteLineIf(CompressionTracingSwitch.Verbose, String.Format(CultureInfo.InvariantCulture, "Literal: {0}", b), "Compression");
Debug.Assert(bytesUsed < WindowSize, "Can't add byte when window is full!");
window[end++] = b;
end &= WindowMask;
++bytesUsed;
}
public void WriteLengthDistance(int length, int distance) {
Debug.WriteLineIf(CompressionTracingSwitch.Verbose, String.Format(CultureInfo.InvariantCulture, "Length/Distance: {0}:{1}", length, distance), "Compression");
Debug.Assert((bytesUsed + length) <= WindowSize, "No Enough space");
// move backwards distance bytes in the output stream,
// and copy length bytes from this position to the output stream.
bytesUsed += length;
int copyStart = (end - distance) & WindowMask; // start position for coping.
int border = WindowSize - length;
if (copyStart <= border && end < border) {
if (length <= distance) {
System.Array.Copy(window, copyStart, window, end, length);
end += length;
} else {
// The referenced string may overlap the current
// position; for example, if the last 2 bytes decoded have values
// X and Y, a string reference with
// adds X,Y,X,Y,X to the output stream.
while (length-- > 0) {
window[end++] = window[copyStart++];
}
}
}
else { // copy byte by byte
while (length-- > 0) {
window[end++] = window[copyStart++];
end &= WindowMask;
copyStart &= WindowMask;
}
}
}
// Copy up to length of bytes from input directly.
// This is used for uncompressed block.
public int CopyFrom(InputBuffer input, int length) {
length = Math.Min(Math.Min(length, WindowSize - bytesUsed), input.AvailableBytes);
int copied;
// We might need wrap around to copy all bytes.
int tailLen = WindowSize - end;
if (length > tailLen) {
// copy the first part
copied = input.CopyTo(window, end, tailLen);
if (copied == tailLen) {
// only try to copy the second part if we have enough bytes in input
copied += input.CopyTo(window, 0, length - tailLen);
}
}
else {
// only one copy is needed if there is no wrap around.
copied = input.CopyTo(window, end, length);
}
end = (end + copied) & WindowMask;
bytesUsed += copied;
return copied;
}
// Free space in output window
public int FreeBytes {
get {
return WindowSize - bytesUsed;
}
}
// bytes not consumed in output window
public int AvailableBytes {
get {
return bytesUsed;
}
}
// copy the decompressed bytes to output array.
public int CopyTo(byte[] output, int offset, int length) {
int copy_end;
if (length > bytesUsed) { // we can copy all the decompressed bytes out
copy_end = end;
length = bytesUsed;
} else {
copy_end = (end - bytesUsed + length) & WindowMask; // copy length of bytes
}
int copied = length;
int tailLen = length - copy_end;
if ( tailLen > 0) { // this means we need to copy two parts seperately
// copy tailLen bytes from the end of output window
System.Array.Copy(window, WindowSize - tailLen,
output, offset, tailLen);
offset += tailLen;
length = copy_end;
}
System.Array.Copy(window, copy_end - length, output, offset, length);
bytesUsed -= copied;
Debug.Assert(bytesUsed >= 0, "check this function and find why we copied more bytes than we have");
return copied;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XPathAncestorIterator.cs
- TemplateXamlTreeBuilder.cs
- XmlNamespaceDeclarationsAttribute.cs
- LinqDataSourceDisposeEventArgs.cs
- XmlSerializableWriter.cs
- TypeDescriptionProvider.cs
- CompiledQueryCacheEntry.cs
- MasterPage.cs
- XmlDataSource.cs
- CollectionViewGroup.cs
- GeneralTransform.cs
- QuaternionAnimationBase.cs
- ExpandCollapsePattern.cs
- OracleCommand.cs
- IsolationInterop.cs
- JavascriptCallbackResponseProperty.cs
- Visitors.cs
- ValueSerializerAttribute.cs
- dataSvcMapFileLoader.cs
- ReaderWriterLock.cs
- ProfessionalColors.cs
- Switch.cs
- XmlSchemaAnyAttribute.cs
- TreeNodeEventArgs.cs
- KeyedQueue.cs
- NonceToken.cs
- TypeReference.cs
- BitmapCodecInfo.cs
- AxHostDesigner.cs
- GroupBoxAutomationPeer.cs
- AppDomainInstanceProvider.cs
- DeviceContexts.cs
- CardSpaceException.cs
- SemanticResultValue.cs
- CapabilitiesAssignment.cs
- NetworkAddressChange.cs
- PrimitiveCodeDomSerializer.cs
- AnnotationStore.cs
- _OSSOCK.cs
- DataPager.cs
- streamingZipPartStream.cs
- GetPageCompletedEventArgs.cs
- LogicalTreeHelper.cs
- NegatedConstant.cs
- Win32Native.cs
- WindowsRichEdit.cs
- BitFlagsGenerator.cs
- SqlXmlStorage.cs
- Model3D.cs
- ZipFileInfoCollection.cs
- SmtpReplyReaderFactory.cs
- SecurityMessageProperty.cs
- ObjectDataSourceWizardForm.cs
- EqualityComparer.cs
- DeviceOverridableAttribute.cs
- TrustSection.cs
- CompositeControl.cs
- _TimerThread.cs
- LinkLabel.cs
- ThicknessConverter.cs
- BaseTransportHeaders.cs
- ContextMenu.cs
- SimpleType.cs
- SqlVersion.cs
- TileBrush.cs
- SocketStream.cs
- DocumentXPathNavigator.cs
- HttpRawResponse.cs
- XmlSchema.cs
- TextRunCache.cs
- DataKeyPropertyAttribute.cs
- TimersDescriptionAttribute.cs
- WindowsListViewGroup.cs
- TreeChangeInfo.cs
- Range.cs
- ReadWriteSpinLock.cs
- WorkflowInstanceAbortedRecord.cs
- TransformValueSerializer.cs
- JoinGraph.cs
- NavigationProperty.cs
- CodeDOMUtility.cs
- ToolStripContentPanel.cs
- OuterGlowBitmapEffect.cs
- WebPartTransformerAttribute.cs
- NameScopePropertyAttribute.cs
- ContainerAction.cs
- ChainOfDependencies.cs
- GestureRecognitionResult.cs
- WhitespaceSignificantCollectionAttribute.cs
- PriorityQueue.cs
- DataGridViewComboBoxEditingControl.cs
- Hashtable.cs
- ValueOfAction.cs
- Matrix.cs
- ConfigurationElement.cs
- InlineUIContainer.cs
- UnionCodeGroup.cs
- TableItemPatternIdentifiers.cs
- FlowDocumentFormatter.cs
- XmlTextReader.cs