Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / MS / Internal / IO / Zip / ProgressiveCrcCalculatingStream.cs / 1 / ProgressiveCrcCalculatingStream.cs
//------------------------------------------------------------------------------ //------------- *** WARNING *** //------------- This file is part of a legally monitored development project. //------------- Do not check in changes to this project. Do not raid bugs on this //------------- code in the main PS database. Do not contact the owner of this //------------- code directly. Contact the legal team at ‘ZSLegal’ for assistance. //------------- *** WARNING *** //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // This is an internal stream class that calcuates CRC values progressively // if possible // // History: // 06/03/2005: YoungGK: Initial creation. // //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Windows; // For Exception strings - SRID using MS.Internal.IO.Zip; namespace MS.Internal.IO.Zip { internal class ProgressiveCrcCalculatingStream: Stream { //////////////////////////////////// // Stream section ///////////////////////////////// override public bool CanRead { get { return (_underlyingStream != null && _underlyingStream.CanRead); } } override public bool CanSeek { get { return (_underlyingStream != null && _underlyingStream.CanSeek); } } override public bool CanWrite { get { return (_underlyingStream != null && _underlyingStream.CanWrite); } } override public long Length { get { CheckDisposed(); return _underlyingStream.Length; } } override public long Position { get { CheckDisposed(); return _underlyingStream.Position; } set { CheckDisposed(); _underlyingStream.Position = value; } } public override void SetLength(long newLength) { CheckDisposed(); if (newLength < 0) { throw new ArgumentOutOfRangeException("newLength"); } if (newLength < _highWaterMark) { _highWaterMark = -1; } // We don't do any check if newLength == current length here // this normally should result in no-op, but this will complicate // the logic due to the need of caching the underlying stream length // Not doing this check here might result in CRC check being skipped _underlyingStream.SetLength(newLength); // Setting a new length is the same as write operation // CRC cannot be checked against the to-be-validated CRC anymore _validateCrcWithExpectedCrc = false; // mark the global dirty flag _blockManager.DirtyFlag = true; } override public long Seek(long offset, SeekOrigin origin) { CheckDisposed(); return _underlyingStream.Seek(offset, origin); } override public int Read(byte[] buffer, int offset, int count) { CheckDisposed(); int readCount = 0; // We should calculate CRC accumulatively for the following conditions // 1. Seek is not supported by the underlying stream: this will be the case for // writing stream in streaming mode // 2. This write request is consequtive to the highwater mark of the CRC calculation // 3. This write request is at 0 offset and the CRC hasn't been calculated yet if (!_underlyingStream.CanSeek) // Case #1 { readCount = _underlyingStream.Read(buffer, offset, count); CrcCalculator.Accumulate(buffer, offset, readCount); } else { long originalPosition = _underlyingStream.Position; readCount = _underlyingStream.Read(buffer, offset, count); // This operation needs to be done after Read since read can throw an exception; in that case // we want to preserve the original CRC if (originalPosition == 0 && _highWaterMark == -1) { _highWaterMark = 0; CrcCalculator.ClearCrc(); } if (originalPosition == _highWaterMark) { CrcCalculator.Accumulate(buffer, offset, readCount); _highWaterMark = _underlyingStream.Position; } if (_validateCrcWithExpectedCrc && CanValidateCrcWithoutRead()) { if (CrcCalculator.Crc != _expectedCrc) { throw new FileFormatException(SR.Get(SRID.CorruptedData)); } } } return readCount; } override public void Write(byte[] buffer, int offset, int count) { CheckDisposed(); // We should calculate CRC accumulatively for the following conditions // 1. Seek is not supported by the underlying stream: this will be the case for // writing stream in streaming mode // 2. This write request is consequtive to the highwater mark of the CRC calculation // 3. This write request is at 0 offset and the CRC hasn't been calculated yet if (!_underlyingStream.CanSeek) // Case #1 { _underlyingStream.Write(buffer, offset, count); CrcCalculator.Accumulate(buffer, offset, count); } else { long originalPosition = _underlyingStream.Position; // If we ever fail to Write below _highWaterMark, we want CRC to be recalculated in case // if a caller decides to recover from the error if (originalPosition < _highWaterMark) { _highWaterMark = -1; } _underlyingStream.Write(buffer, offset, count); if (originalPosition == 0) { _highWaterMark = 0; CrcCalculator.ClearCrc(); } if (originalPosition == _highWaterMark) { CrcCalculator.Accumulate(buffer, offset, count); _highWaterMark = _underlyingStream.Position; } } // CRC cannot be checked against the to-be-validated CRC anymore _validateCrcWithExpectedCrc = false; // mark the global dirty flag _blockManager.DirtyFlag = true; } override public void Flush() { CheckDisposed(); _underlyingStream.Flush(); } ///////////////////////////// // Internal Constructor ///////////////////////////// internal ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream) : this(blockManager, underlyingStream, 0) { _validateCrcWithExpectedCrc = false; } internal ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream, UInt32 expectedCrc) { Debug.Assert(underlyingStream != null); Debug.Assert(blockManager != null); _blockManager = blockManager; _underlyingStream = underlyingStream; _validateCrcWithExpectedCrc = true; _expectedCrc = expectedCrc; _highWaterMark = -1; } //------------------------------------------------------ // // Protected Methods // //----------------------------------------------------- ////// Dispose(bool) /// /// ///We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to /// call Dispose() instead of Close(). protected override void Dispose(bool disposing) { try { if (disposing) { //streams wrapping this stream shouldn't pass Dipose calls through // it is responsibility of the BlockManager or LocalFileBlock (in case of Remove) to call // this dispose as appropriate (that is the reason why Flush isn't called here) // multiple calls are fine - just ignore them // and we shouldn't be closing a stream which we do not own _underlyingStream = null; } } finally { base.Dispose(disposing); } } ///////////////////////////// // Internal Methods ///////////////////////////// // !!!!!!!!!!!!!!!!IMPORTANT !!!!!!!!!!!!!!!! // This method doesn't preserve the seek position of the underlying stream. // It (non-preservation of the seek pointer) is mostly done for compression // scenarios in which seeking back in the compressed streams will result in // switching to the expensive simulation stream. This method is only called // from scenarios during Flush Close of the package where position of the // Compressed stream is insignificant internal UInt32 CalculateCrc() { CheckDisposed(); if (_underlyingStream.CanSeek) { long originalPosition = _underlyingStream.Position; if (_highWaterMark == -1) { CrcCalculator.ClearCrc(); _highWaterMark = 0; } if (_highWaterMark < _underlyingStream.Length) { _underlyingStream.Position = _highWaterMark; CrcCalculator.CalculateStreamCrc(_underlyingStream); _highWaterMark = _underlyingStream.Length; } } return CrcCalculator.Crc; } ///////////////////////////// // Private Methods ///////////////////////////// private void CheckDisposed() { if (_underlyingStream == null) { throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); } } private Crc32Calculator CrcCalculator { get { if (_crcCalculator == null) { _crcCalculator = new Crc32Calculator(); } return _crcCalculator; } } private bool CanValidateCrcWithoutRead() { if (_underlyingStream.CanSeek && _highWaterMark == _underlyingStream.Length) { return true; } return false; } // this is only used to switch the dirty flag in case of Write or SetLength // no other communication is done with the BlockManager from this class private ZipIOBlockManager _blockManager; private long _highWaterMark; private Crc32Calculator _crcCalculator; private bool _validateCrcWithExpectedCrc; private UInt32 _expectedCrc; private Stream _underlyingStream; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ //------------- *** WARNING *** //------------- This file is part of a legally monitored development project. //------------- Do not check in changes to this project. Do not raid bugs on this //------------- code in the main PS database. Do not contact the owner of this //------------- code directly. Contact the legal team at ‘ZSLegal’ for assistance. //------------- *** WARNING *** //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // This is an internal stream class that calcuates CRC values progressively // if possible // // History: // 06/03/2005: YoungGK: Initial creation. // //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Windows; // For Exception strings - SRID using MS.Internal.IO.Zip; namespace MS.Internal.IO.Zip { internal class ProgressiveCrcCalculatingStream: Stream { //////////////////////////////////// // Stream section ///////////////////////////////// override public bool CanRead { get { return (_underlyingStream != null && _underlyingStream.CanRead); } } override public bool CanSeek { get { return (_underlyingStream != null && _underlyingStream.CanSeek); } } override public bool CanWrite { get { return (_underlyingStream != null && _underlyingStream.CanWrite); } } override public long Length { get { CheckDisposed(); return _underlyingStream.Length; } } override public long Position { get { CheckDisposed(); return _underlyingStream.Position; } set { CheckDisposed(); _underlyingStream.Position = value; } } public override void SetLength(long newLength) { CheckDisposed(); if (newLength < 0) { throw new ArgumentOutOfRangeException("newLength"); } if (newLength < _highWaterMark) { _highWaterMark = -1; } // We don't do any check if newLength == current length here // this normally should result in no-op, but this will complicate // the logic due to the need of caching the underlying stream length // Not doing this check here might result in CRC check being skipped _underlyingStream.SetLength(newLength); // Setting a new length is the same as write operation // CRC cannot be checked against the to-be-validated CRC anymore _validateCrcWithExpectedCrc = false; // mark the global dirty flag _blockManager.DirtyFlag = true; } override public long Seek(long offset, SeekOrigin origin) { CheckDisposed(); return _underlyingStream.Seek(offset, origin); } override public int Read(byte[] buffer, int offset, int count) { CheckDisposed(); int readCount = 0; // We should calculate CRC accumulatively for the following conditions // 1. Seek is not supported by the underlying stream: this will be the case for // writing stream in streaming mode // 2. This write request is consequtive to the highwater mark of the CRC calculation // 3. This write request is at 0 offset and the CRC hasn't been calculated yet if (!_underlyingStream.CanSeek) // Case #1 { readCount = _underlyingStream.Read(buffer, offset, count); CrcCalculator.Accumulate(buffer, offset, readCount); } else { long originalPosition = _underlyingStream.Position; readCount = _underlyingStream.Read(buffer, offset, count); // This operation needs to be done after Read since read can throw an exception; in that case // we want to preserve the original CRC if (originalPosition == 0 && _highWaterMark == -1) { _highWaterMark = 0; CrcCalculator.ClearCrc(); } if (originalPosition == _highWaterMark) { CrcCalculator.Accumulate(buffer, offset, readCount); _highWaterMark = _underlyingStream.Position; } if (_validateCrcWithExpectedCrc && CanValidateCrcWithoutRead()) { if (CrcCalculator.Crc != _expectedCrc) { throw new FileFormatException(SR.Get(SRID.CorruptedData)); } } } return readCount; } override public void Write(byte[] buffer, int offset, int count) { CheckDisposed(); // We should calculate CRC accumulatively for the following conditions // 1. Seek is not supported by the underlying stream: this will be the case for // writing stream in streaming mode // 2. This write request is consequtive to the highwater mark of the CRC calculation // 3. This write request is at 0 offset and the CRC hasn't been calculated yet if (!_underlyingStream.CanSeek) // Case #1 { _underlyingStream.Write(buffer, offset, count); CrcCalculator.Accumulate(buffer, offset, count); } else { long originalPosition = _underlyingStream.Position; // If we ever fail to Write below _highWaterMark, we want CRC to be recalculated in case // if a caller decides to recover from the error if (originalPosition < _highWaterMark) { _highWaterMark = -1; } _underlyingStream.Write(buffer, offset, count); if (originalPosition == 0) { _highWaterMark = 0; CrcCalculator.ClearCrc(); } if (originalPosition == _highWaterMark) { CrcCalculator.Accumulate(buffer, offset, count); _highWaterMark = _underlyingStream.Position; } } // CRC cannot be checked against the to-be-validated CRC anymore _validateCrcWithExpectedCrc = false; // mark the global dirty flag _blockManager.DirtyFlag = true; } override public void Flush() { CheckDisposed(); _underlyingStream.Flush(); } ///////////////////////////// // Internal Constructor ///////////////////////////// internal ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream) : this(blockManager, underlyingStream, 0) { _validateCrcWithExpectedCrc = false; } internal ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream, UInt32 expectedCrc) { Debug.Assert(underlyingStream != null); Debug.Assert(blockManager != null); _blockManager = blockManager; _underlyingStream = underlyingStream; _validateCrcWithExpectedCrc = true; _expectedCrc = expectedCrc; _highWaterMark = -1; } //------------------------------------------------------ // // Protected Methods // //----------------------------------------------------- ////// Dispose(bool) /// /// ///We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to /// call Dispose() instead of Close(). protected override void Dispose(bool disposing) { try { if (disposing) { //streams wrapping this stream shouldn't pass Dipose calls through // it is responsibility of the BlockManager or LocalFileBlock (in case of Remove) to call // this dispose as appropriate (that is the reason why Flush isn't called here) // multiple calls are fine - just ignore them // and we shouldn't be closing a stream which we do not own _underlyingStream = null; } } finally { base.Dispose(disposing); } } ///////////////////////////// // Internal Methods ///////////////////////////// // !!!!!!!!!!!!!!!!IMPORTANT !!!!!!!!!!!!!!!! // This method doesn't preserve the seek position of the underlying stream. // It (non-preservation of the seek pointer) is mostly done for compression // scenarios in which seeking back in the compressed streams will result in // switching to the expensive simulation stream. This method is only called // from scenarios during Flush Close of the package where position of the // Compressed stream is insignificant internal UInt32 CalculateCrc() { CheckDisposed(); if (_underlyingStream.CanSeek) { long originalPosition = _underlyingStream.Position; if (_highWaterMark == -1) { CrcCalculator.ClearCrc(); _highWaterMark = 0; } if (_highWaterMark < _underlyingStream.Length) { _underlyingStream.Position = _highWaterMark; CrcCalculator.CalculateStreamCrc(_underlyingStream); _highWaterMark = _underlyingStream.Length; } } return CrcCalculator.Crc; } ///////////////////////////// // Private Methods ///////////////////////////// private void CheckDisposed() { if (_underlyingStream == null) { throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); } } private Crc32Calculator CrcCalculator { get { if (_crcCalculator == null) { _crcCalculator = new Crc32Calculator(); } return _crcCalculator; } } private bool CanValidateCrcWithoutRead() { if (_underlyingStream.CanSeek && _highWaterMark == _underlyingStream.Length) { return true; } return false; } // this is only used to switch the dirty flag in case of Write or SetLength // no other communication is done with the BlockManager from this class private ZipIOBlockManager _blockManager; private long _highWaterMark; private Crc32Calculator _crcCalculator; private bool _validateCrcWithExpectedCrc; private UInt32 _expectedCrc; private Stream _underlyingStream; } } // 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
- WebScriptClientGenerator.cs
- GridViewRow.cs
- TypeUtils.cs
- Splitter.cs
- MatrixCamera.cs
- Int32KeyFrameCollection.cs
- EngineSiteSapi.cs
- ObjectManager.cs
- SessionSymmetricMessageSecurityProtocolFactory.cs
- SoapSchemaMember.cs
- SqlReferenceCollection.cs
- OneOfScalarConst.cs
- Token.cs
- BufferedStream.cs
- TemplateNameScope.cs
- TextSpanModifier.cs
- ToolStripGripRenderEventArgs.cs
- DependencyPropertyDescriptor.cs
- BindingCompleteEventArgs.cs
- KernelTypeValidation.cs
- DataGridRelationshipRow.cs
- URI.cs
- DataGridViewCellLinkedList.cs
- SchemaElement.cs
- HeaderElement.cs
- SafeBitVector32.cs
- ImageField.cs
- UInt32Storage.cs
- MessageQueuePermissionAttribute.cs
- PrivilegedConfigurationManager.cs
- HandlerBase.cs
- PriorityItem.cs
- DelegateHelpers.Generated.cs
- SpecularMaterial.cs
- _NativeSSPI.cs
- AutomationIdentifierGuids.cs
- ReferencedType.cs
- GroupBoxDesigner.cs
- WebPartActionVerb.cs
- SystemResources.cs
- QueryInterceptorAttribute.cs
- UIInitializationException.cs
- LinqDataSourceContextEventArgs.cs
- DrawListViewItemEventArgs.cs
- StorageRoot.cs
- HyperLinkStyle.cs
- HttpCachePolicyWrapper.cs
- SpeechUI.cs
- NameSpaceExtractor.cs
- FileUtil.cs
- OracleTimeSpan.cs
- StorageComplexPropertyMapping.cs
- TemplateBindingExtension.cs
- ToolStripContentPanel.cs
- MdiWindowListItemConverter.cs
- ETagAttribute.cs
- DiscoveryMessageSequenceGenerator.cs
- GetIsBrowserClientRequest.cs
- CodeTypeReferenceExpression.cs
- GridViewRowPresenter.cs
- InputLangChangeEvent.cs
- ItemAutomationPeer.cs
- TraceContextEventArgs.cs
- XmlSchemaRedefine.cs
- ConnectionPointGlyph.cs
- FixedSOMTable.cs
- FileDialogCustomPlacesCollection.cs
- Crypto.cs
- Control.cs
- Resources.Designer.cs
- ButtonBaseAdapter.cs
- FileFormatException.cs
- ListViewDataItem.cs
- DecoderBestFitFallback.cs
- GenericRootAutomationPeer.cs
- _CommandStream.cs
- KernelTypeValidation.cs
- Timer.cs
- CommentAction.cs
- PersonalizableAttribute.cs
- XmlSchemaComplexContent.cs
- CommandEventArgs.cs
- cookiecollection.cs
- MediaContextNotificationWindow.cs
- NativeMethods.cs
- MembershipPasswordException.cs
- TemplateEditingFrame.cs
- AttributedMetaModel.cs
- TransformerInfo.cs
- PrintPreviewControl.cs
- DependencyProperty.cs
- NamespaceEmitter.cs
- Array.cs
- ListControl.cs
- DrawingDrawingContext.cs
- ControlBindingsCollection.cs
- JournalEntryListConverter.cs
- ReceiveActivityDesigner.cs
- URL.cs
- ITreeGenerator.cs