Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / MS / Internal / IO / Packaging / CompressEmulationStream.cs / 1 / CompressEmulationStream.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Abstract base class that provides a fully functional Stream on top of different // various compression implementations. // // History: // 07/14/2004: BruceMac: Initial implementation. // 12/06/2005: BruceMac: Split into abstract base class and move DeflateStream // specific implementation into ManagedEmulationStream // 12/16/2005: BruceMac: Reworked to move functionality into IDeflateTransform // interface to avoid calling virtuals from constructor (FxCop rule) //----------------------------------------------------------------------------- using System; using System.IO; using System.IO.Compression; // for DeflateStream using System.Diagnostics; using System.IO.Packaging; using System.Windows; namespace MS.Internal.IO.Packaging { //----------------------------------------------------- // // Internal Members // //----------------------------------------------------- ////// Interface for Deflate transform object that we use to decompress and compress the actual bytes /// interface IDeflateTransform { void Decompress(Stream source, Stream sink); void Compress(Stream source, Stream sink); } ////// Emulates a fully functional stream using restricted functionality DeflateStream and a temp file /// internal class CompressEmulationStream : Stream { //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Stream Methods ////// Return the bytes requested from the container /// /// destination buffer /// offset to write into that buffer /// how many bytes requested ///how many bytes were written into ///. /// The underlying stream, expected to be an IsolatedStorageFileStream, /// is trusted to leave the IO position unchanged in case of an exception. /// public override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count); return _tempStream.Read(buffer, offset, count); } ////// Seek /// /// offset /// origin ///zero public override long Seek(long offset, SeekOrigin origin) { CheckDisposed(); long temp = 0; switch (origin) { case SeekOrigin.Begin: { temp = offset; break; } case SeekOrigin.Current: { checked { temp = _tempStream.Position + offset; } break; } case SeekOrigin.End: { checked { temp = _tempStream.Length + offset; } break; } default: { throw new ArgumentOutOfRangeException("origin", SR.Get(SRID.SeekOriginInvalid)); } } if (temp < 0) { throw new ArgumentException(SR.Get(SRID.SeekNegative)); } return _tempStream.Seek(offset, origin); } ////// SetLength /// public override void SetLength(long newLength) { CheckDisposed(); _tempStream.SetLength(newLength); // truncation always involves change of stream pointer if (newLength < _tempStream.Position) _tempStream.Position = newLength; _dirty = true; } ////// Write /// public override void Write(byte[] buffer, int offset, int count) { CheckDisposed(); PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count); // no-op if (count == 0) return; _tempStream.Write(buffer, offset, count); _dirty = true; } ////// Flush /// ///Flushes to stream (if necessary) public override void Flush() { CheckDisposed(); if (_dirty) { // don't disturb our current position long tempPosition = _tempStream.Position; // compress _tempStream.Position = 0; _baseStream.Position = 0; _transformer.Compress(_tempStream, _baseStream); // restore _tempStream.Position = tempPosition; _baseStream.Flush(); _dirty = false; } } #endregion Stream Methods #region Stream Properties ////// Current logical position within the stream /// public override long Position { get { CheckDisposed(); return _tempStream.Position; } set { CheckDisposed(); if (value < 0) throw new ArgumentException(SR.Get(SRID.SeekNegative)); _tempStream.Position = value; } } ////// Length /// public override long Length { get { CheckDisposed(); return _tempStream.Length; } } ////// Is stream readable? /// ///returns false when called on disposed stream public override bool CanRead { get { return (!_disposed && _baseStream.CanRead); } } ////// Is stream seekable - should be handled by our owner /// ///returns false when called on disposed stream public override bool CanSeek { get { return (!_disposed && _baseStream.CanSeek); } } ////// Is stream writeable? /// ///returns false when called on disposed stream public override bool CanWrite { get { return (!_disposed && _baseStream.CanWrite); } } #endregion #region Internal //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ ////// Constructor /// /// part stream - not closed - caller determines lifetime /// current logical stream position /// should be an IsolatedStorageFileStream - not closed - caller determines lifetime /// class that does the compression/decompression ///This class should only invoked when emulation is required. /// Does not close any given stream, even when Close is called. This means that it requires /// another wrapper Stream class. internal CompressEmulationStream(Stream baseStream, Stream tempStream, long position, IDeflateTransform transformer) { if (position < 0) throw new ArgumentOutOfRangeException("position"); if (baseStream == null) throw new ArgumentNullException("baseStream"); // seek and read required for emulation if (!baseStream.CanSeek) throw new InvalidOperationException(SR.Get(SRID.SeekNotSupported)); if (!baseStream.CanRead) throw new InvalidOperationException(SR.Get(SRID.ReadNotSupported)); if (tempStream == null) throw new ArgumentNullException("tempStream"); if (transformer == null) throw new ArgumentNullException("transfomer"); _baseStream = baseStream; _tempStream = tempStream; _transformer = transformer; // extract to temporary stream _baseStream.Position = 0; _tempStream.Position = 0; _transformer.Decompress(baseStream, tempStream); // seek to the current logical position _tempStream.Position = position; } #endregion //----------------------------------------------------- // // 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) { if (!_disposed) { Flush(); _tempStream.Close(); _tempStream = null; // never close base stream - we don't own it // _baseStream.Close(); _baseStream = null; _disposed = true; } } } finally { base.Dispose(disposing); } } ////// Call this before accepting any public API call (except some Stream calls that /// are allowed to respond even when Closed /// protected void CheckDisposed() { if (_disposed) throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); } #region Private //----------------------------------------------------- // // Private Variables // //----------------------------------------------------- private bool _disposed; // disposed? private bool _dirty; // do we need to recompress? protected Stream _baseStream; // stream we ultimately decompress from and to in the container protected Stream _tempStream; // temporary storage for the uncompressed stream IDeflateTransform _transformer; // does the actual compress/decompress for us #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Abstract base class that provides a fully functional Stream on top of different // various compression implementations. // // History: // 07/14/2004: BruceMac: Initial implementation. // 12/06/2005: BruceMac: Split into abstract base class and move DeflateStream // specific implementation into ManagedEmulationStream // 12/16/2005: BruceMac: Reworked to move functionality into IDeflateTransform // interface to avoid calling virtuals from constructor (FxCop rule) //----------------------------------------------------------------------------- using System; using System.IO; using System.IO.Compression; // for DeflateStream using System.Diagnostics; using System.IO.Packaging; using System.Windows; namespace MS.Internal.IO.Packaging { //----------------------------------------------------- // // Internal Members // //----------------------------------------------------- ////// Interface for Deflate transform object that we use to decompress and compress the actual bytes /// interface IDeflateTransform { void Decompress(Stream source, Stream sink); void Compress(Stream source, Stream sink); } ////// Emulates a fully functional stream using restricted functionality DeflateStream and a temp file /// internal class CompressEmulationStream : Stream { //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Stream Methods ////// Return the bytes requested from the container /// /// destination buffer /// offset to write into that buffer /// how many bytes requested ///how many bytes were written into ///. /// The underlying stream, expected to be an IsolatedStorageFileStream, /// is trusted to leave the IO position unchanged in case of an exception. /// public override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count); return _tempStream.Read(buffer, offset, count); } ////// Seek /// /// offset /// origin ///zero public override long Seek(long offset, SeekOrigin origin) { CheckDisposed(); long temp = 0; switch (origin) { case SeekOrigin.Begin: { temp = offset; break; } case SeekOrigin.Current: { checked { temp = _tempStream.Position + offset; } break; } case SeekOrigin.End: { checked { temp = _tempStream.Length + offset; } break; } default: { throw new ArgumentOutOfRangeException("origin", SR.Get(SRID.SeekOriginInvalid)); } } if (temp < 0) { throw new ArgumentException(SR.Get(SRID.SeekNegative)); } return _tempStream.Seek(offset, origin); } ////// SetLength /// public override void SetLength(long newLength) { CheckDisposed(); _tempStream.SetLength(newLength); // truncation always involves change of stream pointer if (newLength < _tempStream.Position) _tempStream.Position = newLength; _dirty = true; } ////// Write /// public override void Write(byte[] buffer, int offset, int count) { CheckDisposed(); PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count); // no-op if (count == 0) return; _tempStream.Write(buffer, offset, count); _dirty = true; } ////// Flush /// ///Flushes to stream (if necessary) public override void Flush() { CheckDisposed(); if (_dirty) { // don't disturb our current position long tempPosition = _tempStream.Position; // compress _tempStream.Position = 0; _baseStream.Position = 0; _transformer.Compress(_tempStream, _baseStream); // restore _tempStream.Position = tempPosition; _baseStream.Flush(); _dirty = false; } } #endregion Stream Methods #region Stream Properties ////// Current logical position within the stream /// public override long Position { get { CheckDisposed(); return _tempStream.Position; } set { CheckDisposed(); if (value < 0) throw new ArgumentException(SR.Get(SRID.SeekNegative)); _tempStream.Position = value; } } ////// Length /// public override long Length { get { CheckDisposed(); return _tempStream.Length; } } ////// Is stream readable? /// ///returns false when called on disposed stream public override bool CanRead { get { return (!_disposed && _baseStream.CanRead); } } ////// Is stream seekable - should be handled by our owner /// ///returns false when called on disposed stream public override bool CanSeek { get { return (!_disposed && _baseStream.CanSeek); } } ////// Is stream writeable? /// ///returns false when called on disposed stream public override bool CanWrite { get { return (!_disposed && _baseStream.CanWrite); } } #endregion #region Internal //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ ////// Constructor /// /// part stream - not closed - caller determines lifetime /// current logical stream position /// should be an IsolatedStorageFileStream - not closed - caller determines lifetime /// class that does the compression/decompression ///This class should only invoked when emulation is required. /// Does not close any given stream, even when Close is called. This means that it requires /// another wrapper Stream class. internal CompressEmulationStream(Stream baseStream, Stream tempStream, long position, IDeflateTransform transformer) { if (position < 0) throw new ArgumentOutOfRangeException("position"); if (baseStream == null) throw new ArgumentNullException("baseStream"); // seek and read required for emulation if (!baseStream.CanSeek) throw new InvalidOperationException(SR.Get(SRID.SeekNotSupported)); if (!baseStream.CanRead) throw new InvalidOperationException(SR.Get(SRID.ReadNotSupported)); if (tempStream == null) throw new ArgumentNullException("tempStream"); if (transformer == null) throw new ArgumentNullException("transfomer"); _baseStream = baseStream; _tempStream = tempStream; _transformer = transformer; // extract to temporary stream _baseStream.Position = 0; _tempStream.Position = 0; _transformer.Decompress(baseStream, tempStream); // seek to the current logical position _tempStream.Position = position; } #endregion //----------------------------------------------------- // // 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) { if (!_disposed) { Flush(); _tempStream.Close(); _tempStream = null; // never close base stream - we don't own it // _baseStream.Close(); _baseStream = null; _disposed = true; } } } finally { base.Dispose(disposing); } } ////// Call this before accepting any public API call (except some Stream calls that /// are allowed to respond even when Closed /// protected void CheckDisposed() { if (_disposed) throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); } #region Private //----------------------------------------------------- // // Private Variables // //----------------------------------------------------- private bool _disposed; // disposed? private bool _dirty; // do we need to recompress? protected Stream _baseStream; // stream we ultimately decompress from and to in the container protected Stream _tempStream; // temporary storage for the uncompressed stream IDeflateTransform _transformer; // does the actual compress/decompress for us #endregion } } // 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
- AmbientProperties.cs
- IdentitySection.cs
- ExtentKey.cs
- ThreadStaticAttribute.cs
- AssociationType.cs
- DataGridViewRowsAddedEventArgs.cs
- ServiceObjectContainer.cs
- ClassicBorderDecorator.cs
- StorageEntityTypeMapping.cs
- TableLayoutSettingsTypeConverter.cs
- HttpCachePolicy.cs
- EarlyBoundInfo.cs
- IProducerConsumerCollection.cs
- XmlCodeExporter.cs
- XmlSerializerAssemblyAttribute.cs
- AsymmetricSignatureFormatter.cs
- OraclePermission.cs
- RequestCacheEntry.cs
- SqlTopReducer.cs
- GraphicsState.cs
- PostBackTrigger.cs
- PageParser.cs
- ServiceModelSecurityTokenRequirement.cs
- GPRECT.cs
- SHA384Managed.cs
- ValueProviderWrapper.cs
- CommonXSendMessage.cs
- XPathNodeHelper.cs
- Point3DConverter.cs
- OdbcConnectionPoolProviderInfo.cs
- Camera.cs
- wgx_render.cs
- XmlSchemaNotation.cs
- ServerIdentity.cs
- URLString.cs
- SchemaImporterExtensionsSection.cs
- EnvelopedPkcs7.cs
- ADMembershipUser.cs
- VectorCollection.cs
- PointIndependentAnimationStorage.cs
- ELinqQueryState.cs
- ControlBuilder.cs
- TypeElement.cs
- XmlIlTypeHelper.cs
- _TransmitFileOverlappedAsyncResult.cs
- HttpApplicationFactory.cs
- GridViewPageEventArgs.cs
- WindowsListViewScroll.cs
- WCFBuildProvider.cs
- TableItemPatternIdentifiers.cs
- CannotUnloadAppDomainException.cs
- DoubleLinkList.cs
- CqlParser.cs
- ColumnWidthChangingEvent.cs
- GZipDecoder.cs
- MatchingStyle.cs
- BaseTemplateParser.cs
- FileFormatException.cs
- DrawListViewSubItemEventArgs.cs
- XmlDigitalSignatureProcessor.cs
- GridViewDeleteEventArgs.cs
- MimeTypePropertyAttribute.cs
- SingleBodyParameterMessageFormatter.cs
- Selector.cs
- ResolveNameEventArgs.cs
- MaterialGroup.cs
- ParameterReplacerVisitor.cs
- ArraySegment.cs
- KeyConverter.cs
- Int64Animation.cs
- MetadataSerializer.cs
- DataRecordObjectView.cs
- Vector3DValueSerializer.cs
- InputMethodStateChangeEventArgs.cs
- StrongNamePublicKeyBlob.cs
- PeerCollaborationPermission.cs
- Util.cs
- Policy.cs
- EntityObject.cs
- SchemeSettingElement.cs
- PriorityBindingExpression.cs
- GlyphRunDrawing.cs
- Columns.cs
- ListCollectionView.cs
- PublisherIdentityPermission.cs
- AuthenticationManager.cs
- DesignerUtility.cs
- XslCompiledTransform.cs
- DataGridViewRowPostPaintEventArgs.cs
- ByteFacetDescriptionElement.cs
- VisualStyleRenderer.cs
- Splitter.cs
- ProfilePropertySettings.cs
- FixedPosition.cs
- webproxy.cs
- COM2IDispatchConverter.cs
- AnimatedTypeHelpers.cs
- ClonableStack.cs
- LoadRetryStrategyFactory.cs
- BCLDebug.cs