Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / IO / Zip / ProgressiveCrcCalculatingStream.cs / 1305600 / 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: [....]: Initial creation. // //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Windows; // For Exception strings - SRID using MS.Internal.IO.Zip; using MS.Internal.WindowsBase; 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: [....]: Initial creation. // //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Windows; // For Exception strings - SRID using MS.Internal.IO.Zip; using MS.Internal.WindowsBase; 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
- GeometryDrawing.cs
- PrintDialog.cs
- XmlSerializerFaultFormatter.cs
- InstanceData.cs
- CommandDevice.cs
- TextServicesPropertyRanges.cs
- CoreSwitches.cs
- NonParentingControl.cs
- ManagementScope.cs
- MimeWriter.cs
- CfgParser.cs
- HandlerMappingMemo.cs
- IpcManager.cs
- MorphHelpers.cs
- DateTimeUtil.cs
- RefType.cs
- ListViewEditEventArgs.cs
- MasterPageCodeDomTreeGenerator.cs
- ObjectViewListener.cs
- Win32MouseDevice.cs
- TextServicesManager.cs
- ACE.cs
- PictureBox.cs
- relpropertyhelper.cs
- DataControlPagerLinkButton.cs
- ZipPackagePart.cs
- ColorTranslator.cs
- InstanceKeyCollisionException.cs
- Mouse.cs
- isolationinterop.cs
- SafeCryptHandles.cs
- PageClientProxyGenerator.cs
- XmlSchemaObject.cs
- DesignBindingConverter.cs
- HttpModulesSection.cs
- RelationshipNavigation.cs
- WpfXamlType.cs
- CredentialCache.cs
- DataControlFieldCollection.cs
- WebServiceParameterData.cs
- ProgressPage.cs
- XmlNotation.cs
- ServiceDefaults.cs
- WebCategoryAttribute.cs
- EastAsianLunisolarCalendar.cs
- StatusBarAutomationPeer.cs
- CodeEventReferenceExpression.cs
- DocumentOrderQuery.cs
- ReverseComparer.cs
- TagPrefixCollection.cs
- ExclusiveTcpTransportManager.cs
- CurrentChangingEventManager.cs
- ThreadExceptionDialog.cs
- PersonalizationState.cs
- HTMLTagNameToTypeMapper.cs
- ImageSourceValueSerializer.cs
- LayoutUtils.cs
- ScriptControlManager.cs
- CustomAttributeBuilder.cs
- UserPersonalizationStateInfo.cs
- ProgressBar.cs
- TemplateBamlTreeBuilder.cs
- MarkerProperties.cs
- ConfigurationElementProperty.cs
- Oci.cs
- controlskin.cs
- DataGridViewTextBoxCell.cs
- ProviderIncompatibleException.cs
- CachedBitmap.cs
- PopOutPanel.cs
- DataObjectEventArgs.cs
- ElementNotEnabledException.cs
- RelationshipEndMember.cs
- EdmRelationshipRoleAttribute.cs
- HttpDictionary.cs
- Quaternion.cs
- TextHidden.cs
- SettingsPropertyNotFoundException.cs
- RoutedEventValueSerializer.cs
- DateTimeOffsetStorage.cs
- Variant.cs
- RecordsAffectedEventArgs.cs
- Scripts.cs
- WebPartConnectionsCancelVerb.cs
- SafeMarshalContext.cs
- AnnotationMap.cs
- Wizard.cs
- GraphicsContext.cs
- SmiRecordBuffer.cs
- WorkflowOperationBehavior.cs
- CodeExpressionStatement.cs
- Attribute.cs
- BoundPropertyEntry.cs
- XmlBaseWriter.cs
- EntityReference.cs
- InvalidOperationException.cs
- QilName.cs
- AdapterUtil.cs
- WinHttpWebProxyFinder.cs
- XmlnsDefinitionAttribute.cs