Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Base / MS / Internal / IO / Packaging / CompoundFile / VersionedStreamOwner.cs / 1 / VersionedStreamOwner.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // This class provides file versioning support for streams provided by // IDataTransform implementations and any client code that needs // to store a FormatVersion at the beginning of a stream. // // History: // 02/21/2006: [....]: Initial implementation. // //----------------------------------------------------------------------------- using System; using System.IO; // for Stream using System.Windows; // ExceptionStringTable using System.Globalization; // for CultureInfo using System.Diagnostics; // for Debug.Assert namespace MS.Internal.IO.Packaging.CompoundFile { ////// Specialized stream that owns the FormatVersion /// ///Dispose() functionality is handled by our subclass VersionedStream internal class VersionedStreamOwner : VersionedStream { #region Stream Methods ////// Return the bytes requested from the container /// public override int Read(byte[] buffer, int offset, int count) { // throw if version missing ReadAttempt(true); return BaseStream.Read(buffer, offset, count); } ////// Write /// public override void Write(byte[] buffer, int offset, int count) { WriteAttempt(); BaseStream.Write(buffer, offset, count); } ////// ReadByte /// public override int ReadByte() { ReadAttempt(true); return BaseStream.ReadByte(); } ////// WriteByte /// public override void WriteByte(byte b) { WriteAttempt(); BaseStream.WriteByte(b); } ////// Seek /// /// offset /// origin ///zero public override long Seek(long offset, SeekOrigin origin) { ReadAttempt(); long temp = -1; switch (origin) { // seek beyond the FormatVersion case SeekOrigin.Begin: temp = offset; break; case SeekOrigin.Current: checked { temp = Position + offset; } break; case SeekOrigin.End: checked { temp = Length + offset; } break; } if (temp < 0) throw new ArgumentException(SR.Get(SRID.SeekNegative)); checked { BaseStream.Position = temp + _dataOffset; } return temp; } ////// SetLength /// public override void SetLength(long newLength) { if (newLength < 0) throw new ArgumentOutOfRangeException("newLength"); WriteAttempt(); checked { BaseStream.SetLength(newLength + _dataOffset); } } ////// Flush /// public override void Flush() { CheckDisposed(); BaseStream.Flush(); } #endregion Stream Methods //----------------------------------------------------- // // Public Properties // //----------------------------------------------------- #region Stream Properties ////// Current logical position within the stream /// public override long Position { get { ReadAttempt(); // ensure _dataOffset is valid return checked(BaseStream.Position - _dataOffset); } set { // share Seek logic and validation Seek(value, SeekOrigin.Begin); } } ////// Length /// public override long Length { get { ReadAttempt(); // ensure _dataOffset is valid long temp = checked(BaseStream.Length - _dataOffset); Invariant.Assert(temp >= 0); // catch any math errors return temp; } } ////// Is stream readable? /// ///returns false when called on disposed stream public override bool CanRead { get { return (BaseStream != null) && BaseStream.CanRead && IsReadable; } } ////// Is stream seekable - should be handled by our owner /// ///returns false when called on disposed stream public override bool CanSeek { get { return (BaseStream != null) && BaseStream.CanSeek && IsReadable; } } ////// Is stream writeable? /// ///returns false when called on disposed stream public override bool CanWrite { get { return (BaseStream != null) && BaseStream.CanWrite && IsUpdatable; } } #endregion ////// Constructor to use for the "versioned stream" - the one that actually houses the /// persisted FormatVersion. /// /// /// internal VersionedStreamOwner(Stream baseStream, FormatVersion codeVersion) : base(baseStream) { _codeVersion = codeVersion; } internal bool IsUpdatable { get { CheckDisposed(); // first try to read the format version EnsureParsed(); // We can write if either: // 1. FileVersion doesn't exist - this is normal for a new, empty stream // 2. It does exist and the FormatVersion indicates that we can update it return (_fileVersion == null) || _fileVersion.IsUpdatableBy(_codeVersion.UpdaterVersion); } } internal bool IsReadable { get { CheckDisposed(); // first try to read the format version EnsureParsed(); // We can read if either: // 1. FileVersion doesn't exist - normal for a new, empty stream // 1. FileVersion exists and indicates that we can read it return (_fileVersion == null) || _fileVersion.IsReadableBy(_codeVersion.ReaderVersion); } } ////// Callback for when a stream is written to /// ///Can modify the FormatVersion stream pointer. internal void WriteAttempt() { CheckDisposed(); // central location if (!_writeOccurred) { // first try to read the format version EnsureParsed(); if (_fileVersion == null) { // stream is empty so write our version PersistVersion(_codeVersion); } else { // file version found - ensure we are able to update it if (!_fileVersion.IsUpdatableBy(_codeVersion.UpdaterVersion)) { throw new FileFormatException( SR.Get( SRID.UpdaterVersionError, _fileVersion.UpdaterVersion, _codeVersion ) ); } // if our version is different than previous // updater then "update" the updater if (_codeVersion.UpdaterVersion != _fileVersion.UpdaterVersion) { _fileVersion.UpdaterVersion = _codeVersion.UpdaterVersion; PersistVersion(_fileVersion); } } _writeOccurred = true; } } internal void ReadAttempt() { ReadAttempt(false); } ////// Callback for when a Stream is read from /// ///Can modify the FormatVersion stream pointer. /// caller requires an existing FormatVersion internal void ReadAttempt(bool throwIfEmpty) { CheckDisposed(); // central location // only do this once if (!_readOccurred) { // read EnsureParsed(); // first usage? if (throwIfEmpty || BaseStream.Length > 0) { if (_fileVersion == null) throw new FileFormatException(SR.Get(SRID.VersionStreamMissing)); // compare versions // verify we can read this version if (!_fileVersion.IsReadableBy(_codeVersion.ReaderVersion)) { throw new FileFormatException( SR.Get( SRID.ReaderVersionError, _fileVersion.ReaderVersion, _codeVersion ) ); } } _readOccurred = true; } } //------------------------------------------------------ // // Private Methods // //----------------------------------------------------- ////// Ensure that the version is persisted /// ///Leaves stream at position just after the FormatVersion. /// Destructive. This is called automatically from WriteAttempt but callers /// can call directly if they have changed the stream contents to a format /// that is no longer compatible with the persisted FormatVersion. If /// this is not called directly, and a FormatVersion was found in the file /// then only the Updater field is modified. /// private void PersistVersion(FormatVersion version) { if (!BaseStream.CanWrite) throw new NotSupportedException(SR.Get(SRID.WriteNotSupported)); // normalize and save long tempPos = checked(BaseStream.Position - _dataOffset); BaseStream.Seek(0, SeekOrigin.Begin); // update _dataOffset long offset = version.SaveToStream(BaseStream); _fileVersion = version; // we know what it is - no need to deserialize // existing value - ensure we didn't change sizes as this could lead to // data corruption if ((_dataOffset != 0) && (offset != _dataOffset)) throw new FileFormatException(SR.Get(SRID.VersionUpdateFailure)); // at this point we know the offset _dataOffset = offset; // restore and shift checked { BaseStream.Position = tempPos + _dataOffset; } } ////// Load and compare feature identifier /// ///There is no need for this method to maintain any previous Seek pointer. /// This method only modifies the stream position when called for the first time with a non-empty /// stream. It is always called from Seek() and set_Position, which subsequently modify the stream /// pointer as appropriate after the call. private void EnsureParsed() { // empty stream cannot have a version in it if ((_fileVersion == null) && (BaseStream.Length > 0)) { Debug.Assert(_dataOffset == 0); // if no version was found and we cannot read from it, then the format is invalid if (!BaseStream.CanRead) throw new NotSupportedException(SR.Get(SRID.ReadNotSupported)); // // The physical stream begins with a header that identifies the transform to // which the stream belongs. The "logical" stream object handed to us by the // compound file begins -after- this stream header, so when we seek to the // "beginning" of this stream, we are actually seeking to the location after // the stream header, where the instance data starts. // BaseStream.Seek(0, SeekOrigin.Begin); // // The instance data starts with format version information for this transform. // _fileVersion = FormatVersion.LoadFromStream(BaseStream); // // Ensure that the feature name is as expected. // // NOTE: We preserve case, but do case-insensitive comparison. if (String.CompareOrdinal( _fileVersion.FeatureIdentifier.ToUpper(CultureInfo.InvariantCulture), _codeVersion.FeatureIdentifier.ToUpper(CultureInfo.InvariantCulture)) != 0) { throw new FileFormatException( SR.Get( SRID.InvalidTransformFeatureName, _fileVersion.FeatureIdentifier, _codeVersion.FeatureIdentifier ) ); } _dataOffset = BaseStream.Position; } } //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ private bool _writeOccurred; // did one of our streams get written to? private bool _readOccurred; // did one of our streams get read from? private FormatVersion _codeVersion; // code version private FormatVersion _fileVersion; // current file version (null if not read or created yet) private long _dataOffset = 0; // where FormatVersion ends and data begins } } // 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
- SvcMapFileSerializer.cs
- entityreference_tresulttype.cs
- WebColorConverter.cs
- ISAPIRuntime.cs
- ComPersistableTypeElementCollection.cs
- ClonableStack.cs
- XPathDocumentIterator.cs
- DataControlPagerLinkButton.cs
- ColumnClickEvent.cs
- CodeIdentifiers.cs
- mactripleDES.cs
- CollectionsUtil.cs
- Permission.cs
- PolyBezierSegmentFigureLogic.cs
- HyperLinkColumn.cs
- ShapeTypeface.cs
- MessageSecurityVersion.cs
- HtmlLabelAdapter.cs
- CompiledQuery.cs
- XmlCountingReader.cs
- FontClient.cs
- ThicknessConverter.cs
- SystemIPv4InterfaceProperties.cs
- precedingquery.cs
- CompilerScope.cs
- TextFormatterHost.cs
- ObjRef.cs
- contentDescriptor.cs
- VisualTreeHelper.cs
- NegatedCellConstant.cs
- EncryptionUtility.cs
- TabControlCancelEvent.cs
- Visual3DCollection.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- PrivateUnsafeNativeCompoundFileMethods.cs
- EnumDataContract.cs
- HtmlValidatorAdapter.cs
- Object.cs
- SmtpFailedRecipientsException.cs
- WindowsScrollBar.cs
- SiteMapDataSource.cs
- TextServicesDisplayAttribute.cs
- RtType.cs
- x509utils.cs
- ListenerElementsCollection.cs
- FormsAuthenticationModule.cs
- ImportException.cs
- TriState.cs
- XpsDocument.cs
- HwndHostAutomationPeer.cs
- XmlReflectionMember.cs
- Resources.Designer.cs
- LinqMaximalSubtreeNominator.cs
- DataGridCommandEventArgs.cs
- SystemIPGlobalProperties.cs
- BeginCreateSecurityTokenRequest.cs
- WebRequest.cs
- MsmqBindingFilter.cs
- TemplateBindingExtensionConverter.cs
- StrokeRenderer.cs
- FixedDocumentSequencePaginator.cs
- BitHelper.cs
- MailWebEventProvider.cs
- PagedControl.cs
- RelatedCurrencyManager.cs
- CurrentChangingEventManager.cs
- EpmContentSerializerBase.cs
- ApplicationSecurityManager.cs
- XmlSchemaParticle.cs
- LogicalExpressionEditor.cs
- OrthographicCamera.cs
- EdmFunctions.cs
- PathSegment.cs
- GroupBoxAutomationPeer.cs
- AggregateException.cs
- WebPageTraceListener.cs
- SimpleModelProvider.cs
- JsonStringDataContract.cs
- regiisutil.cs
- CodeSubDirectory.cs
- GeneralTransform3DGroup.cs
- HttpListenerTimeoutManager.cs
- DummyDataSource.cs
- InvalidWMPVersionException.cs
- PathGradientBrush.cs
- FixedTextView.cs
- PatternMatcher.cs
- SqlProviderManifest.cs
- SimpleHandlerBuildProvider.cs
- Parameter.cs
- EntityViewGenerationAttribute.cs
- RoleBoolean.cs
- ScrollChrome.cs
- mil_sdk_version.cs
- ScriptComponentDescriptor.cs
- Table.cs
- SqlWebEventProvider.cs
- SystemColors.cs
- Win32Native.cs
- DataControlFieldTypeEditor.cs