Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / 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
- SingleKeyFrameCollection.cs
- Helpers.cs
- CallbackValidatorAttribute.cs
- LogicalExpr.cs
- TrackingConditionCollection.cs
- Timer.cs
- EntityDataSourceState.cs
- DocobjHost.cs
- CompiledRegexRunnerFactory.cs
- HiddenFieldPageStatePersister.cs
- IApplicationTrustManager.cs
- AutoCompleteStringCollection.cs
- WindowsToolbar.cs
- CompoundFileStreamReference.cs
- BaseCollection.cs
- HwndAppCommandInputProvider.cs
- HtmlElementErrorEventArgs.cs
- Highlights.cs
- RoleProviderPrincipal.cs
- IItemContainerGenerator.cs
- Label.cs
- PersonalizableAttribute.cs
- TypeSystem.cs
- EraserBehavior.cs
- SQLCharsStorage.cs
- EntityPropertyMappingAttribute.cs
- MouseActionConverter.cs
- RepeatBehavior.cs
- LabelEditEvent.cs
- SpellerError.cs
- LongMinMaxAggregationOperator.cs
- RuntimeArgument.cs
- CompositeActivityValidator.cs
- ConsumerConnectionPoint.cs
- TypeRestriction.cs
- IssuanceLicense.cs
- Identity.cs
- ImageMapEventArgs.cs
- FormsAuthenticationUser.cs
- QilDataSource.cs
- XMLSchema.cs
- Evidence.cs
- EndOfStreamException.cs
- XPathParser.cs
- Thread.cs
- RelationshipEndCollection.cs
- FormsAuthenticationUserCollection.cs
- DbgCompiler.cs
- Soap.cs
- ProfileWorkflowElement.cs
- SimpleWorkerRequest.cs
- SqlDataSource.cs
- DataContractJsonSerializer.cs
- ForwardPositionQuery.cs
- ErrorProvider.cs
- RuntimeHelpers.cs
- ControlPropertyNameConverter.cs
- Regex.cs
- LicenseContext.cs
- ConfigurationStrings.cs
- CommonRemoteMemoryBlock.cs
- CompiledAction.cs
- FileRecordSequenceHelper.cs
- CheckBox.cs
- CodeFieldReferenceExpression.cs
- MimeTypeMapper.cs
- CollectionConverter.cs
- WebBrowserPermission.cs
- AddInBase.cs
- ManagementQuery.cs
- cookieexception.cs
- ManagementObjectSearcher.cs
- AssemblyBuilder.cs
- SafeCertificateStore.cs
- FixUp.cs
- WebResourceAttribute.cs
- EpmSourceTree.cs
- ConfigurationPermission.cs
- ContextMenuStripGroupCollection.cs
- CodeIdentifiers.cs
- XhtmlBasicLiteralTextAdapter.cs
- RowVisual.cs
- XmlSchemaObjectCollection.cs
- CriticalHandle.cs
- PinnedBufferMemoryStream.cs
- GridPattern.cs
- PrefixQName.cs
- Pointer.cs
- WebPartCatalogAddVerb.cs
- InputMethod.cs
- CharKeyFrameCollection.cs
- Vector.cs
- _UriTypeConverter.cs
- ToolStripPanelCell.cs
- MimeBasePart.cs
- GradientBrush.cs
- ToolZone.cs
- HtmlEncodedRawTextWriter.cs
- updateconfighost.cs
- SchemaMerger.cs