Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / System / Windows / Markup / TreeBuilderBamlTranslator.cs / 1 / TreeBuilderBamlTranslator.cs
/****************************************************************************\ * * File: TreeBuilderBamlTranslator.cs * * Purpose: Class that builds a stream from BAML * * History: * 6/06/01: rogerg Created * 5/29/03: peterost Ported to wcp * * Copyright (C) 2003 by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using System; using System.Xml; using System.IO; using System.Windows; using System.Text; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Threading; using MS.Internal; using MS.Utility; // Disabling 1634 and 1691: // In order to avoid generating warnings about unknown message numbers and // unknown pragmas when compiling C# source code with the C# compiler, // you need to disable warnings 1634 and 1691. (Presharp Documentation) #pragma warning disable 1634, 1691 #if PBTCOMPILER namespace MS.Internal.Markup #else namespace System.Windows.Markup #endif { ////// TreeBuilder implementation for building a Tree from BAML /// internal class TreeBuilderBamlTranslator : TreeBuilder { #if !PBTCOMPILER #region Constructors ////// Constructor. If closeBamlStream is true, then the parser is the owner of the /// owner of the stream, and will close the stream when finished parsing. /// internal TreeBuilderBamlTranslator( Stream bamlStream, ParserContext parserContext, object parent, bool closeBamlStream) : base() { _bamlStream = bamlStream; _closeBamlStream = closeBamlStream; Debug.Assert(null != parserContext.XamlTypeMapper); RecordReader = new BamlRecordReader(bamlStream, parserContext, parent); } // internal constructor to allow subclassing. internal TreeBuilderBamlTranslator() { } #endregion Constructors #region Overrides ////// Internal Avalon method. Used to parse a BAML file. /// ///An array containing the root objects in the BAML stream public override object ParseFragment() { bool asyncParse = false; // only close stream if not in Async parse mode. try { RecordReader.Initialize(); RecordReader.ReadVersionHeader(); // if baml, read the start document and get the ParseMode. // Review, should probably be done in Parse() BamlRecordType recType = (BamlRecordType)RecordReader.BinaryReader.ReadByte(); if (recType != BamlRecordType.DocumentStart) { throw new InvalidOperationException(); } BamlRecord bamlRecord = RecordReader.BamlRecordManager.ReadNextRecord( RecordReader.BinaryReader, Int64.MaxValue, recType); Debug.Assert(null != bamlRecord); Debug.Assert(bamlRecord.RecordType == BamlRecordType.DocumentStart); BamlDocumentStartRecord bamlStartDoc = bamlRecord as BamlDocumentStartRecord; if (null != bamlStartDoc) { // SetParse Mode may have already change the ParseMode so // only use what is in the record if still Uninitialized. if ( XamlParseMode == XamlParseMode.Uninitialized ) { #if SUPPORTBAMLASYNC // For M11 we will not support async loading of baml files. They // will all be treated as synchronous. This is done to reduce // surface area, as described in windows bug # 1079575 if (bamlStartDoc.LoadAsync) { XamlParseMode = XamlParseMode.Asynchronous; } else #endif { XamlParseMode = XamlParseMode.Synchronous; } } MaxAsyncRecords = bamlStartDoc.MaxAsyncRecords; } // Set associated record reader async info to what has been found so far RecordReader.XamlParseMode = XamlParseMode; RecordReader.MaxAsyncRecords = MaxAsyncRecords; RecordReader.IsDebugBamlStream = bamlStartDoc.DebugBaml; Debug.Assert(XamlParseMode != XamlParseMode.Uninitialized); // if in synchronous mode then just read the baml stream and then // return. if going into async mode then build up the first tag // synchronously and then post a queue item. // Note that we don't actually go into async mode for compiling. if (XamlParseMode == XamlParseMode.Synchronous) { RecordReader.Read(); TreeBuildComplete(); //Debug.Assert(1 >= RootList.Count, "Cannot have multiple root elements in BAML stream"); } else { // read in the first record since binder at present // needs this. bool moreData = true; // sit in synchronous read until get first root. Need this // until we get async binder support. while (GetRoot() == null && moreData) { moreData = RecordReader.Read(true /* single record mode*/); } if (moreData && GetRoot() == null) { // before going async want to switch to async stream interfaces // so we don't block on I/O. // setup stream Manager on Reader and kick of Async Writes StreamManager = new ReadWriteStreamManager(); // RecordReader no points to the ReaderWriter stream which // is different from our BAMLStream member. RecordReader.BamlStream = StreamManager.ReaderStream; // now spin a thread to read the BAML. This can change // once we get Read support that fails if contents isn't // available instead of blocks. asyncParse = true; ThreadStart threadStart = new ThreadStart(ReadBamlAsync); Thread thread = new Thread(threadStart); thread.Start(); // post a work item to do the rest. Post(); } else { // if don't get a root or there isn't any moredata then // we are done building. TreeBuildComplete(); } } } finally { // If not in an async parse and we are told to close the // stream explicitly, then we are done with the input stream. // Otherwise rely on the async thread calling Close if (!asyncParse) { CloseBamlInputStream(); } } return GetRoot(); } ////// called when TreeBuilder gets an Async slice /// we override the base class to see if can close the input stream. /// internal override void HandleAsyncQueueItem() { if (DoneReadingBamlStream) { CloseBamlInputStream(); } base.HandleAsyncQueueItem(); } #endregion overrides #region Methods // Async callback that reads the next chunk from the baml stream, until the // end of the stream has been reached, or we've read a certain number of // records. protected void ReadBamlAsync() { try { // sits in a loop reading BAML // hopefully temporary function not needed when can get read to // just fail if number of requested bytes are not yet available. Debug.Assert(null != StreamManager,"StreamManager is null in Async Read"); Debug.Assert(BamlStream != RecordReader.BamlStream,"Input BAML shouldn't be same as Output"); WriterStream writerStream = StreamManager.WriterStream; int bytesRead; long writtenStreamLength = 0; int maxBufferSize = 256; // for now read 256 at a time. byte[] buffer = new byte[maxBufferSize]; while (!DoneReadingBamlStream) { bytesRead = BamlStream.Read(buffer,0,maxBufferSize); if (0 == bytesRead) { DoneReadingBamlStream = true; } else { writerStream.Write(buffer,0,bytesRead); writtenStreamLength += bytesRead; writerStream.UpdateReaderLength(writtenStreamLength); } } } catch (Exception e) { if (CriticalExceptions.IsCriticalException(e)) { throw; } else { // catch any exception on the async thread and send it over. // make sure you set the exception before the error flag. ParseException = e; } } } ////// Helper Function to close the BamlInputStream. /// This can get called twice in Async, once the first time we /// get on the UI thread after done reading input and second when /// the tree buildComplete occurs so check for NULL /// the queue /// void CloseBamlInputStream() { // possible we have to close // In the straight BamlLoad case we will have a BamlStream to Close // if we are given ownership of the BamlStream in BuildFromBaml. if (null != BamlStream ) { if (_closeBamlStream) { BamlStream.Close(); } // even if we don't own the treat set the member to null _bamlStream = null; } } #endregion Methods #region Properties ////// BamlStream to load from /// protected Stream BamlStream { get { return _bamlStream; } set { _bamlStream = value; } } ////// flag used in Async read sets to true when /// BamlStream has been completely read. /// protected bool DoneReadingBamlStream { get { return _doneReadingBamlStream; } set { _doneReadingBamlStream = value; } } ////// ReaderWriterStream used if we kick off an Async Load. /// protected ReadWriteStreamManager StreamManager { get { return _streamManager; } set { _streamManager = value; } } #endregion Properties #region Data // Manager used to handle the stream operations. ReadWriteStreamManager _streamManager; // Stream of baml records. Stream _bamlStream; // True if the parser owns the baml stream, and can close the stream // when the parse is complete. False if the stream is owned by someone // else, in which case the parser will not close it. bool _closeBamlStream; // True when baml stream has completed reading in async mode. bool _doneReadingBamlStream; #endregion Data #endif // !PBTCOMPILER } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /****************************************************************************\ * * File: TreeBuilderBamlTranslator.cs * * Purpose: Class that builds a stream from BAML * * History: * 6/06/01: rogerg Created * 5/29/03: peterost Ported to wcp * * Copyright (C) 2003 by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using System; using System.Xml; using System.IO; using System.Windows; using System.Text; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Threading; using MS.Internal; using MS.Utility; // Disabling 1634 and 1691: // In order to avoid generating warnings about unknown message numbers and // unknown pragmas when compiling C# source code with the C# compiler, // you need to disable warnings 1634 and 1691. (Presharp Documentation) #pragma warning disable 1634, 1691 #if PBTCOMPILER namespace MS.Internal.Markup #else namespace System.Windows.Markup #endif { ////// TreeBuilder implementation for building a Tree from BAML /// internal class TreeBuilderBamlTranslator : TreeBuilder { #if !PBTCOMPILER #region Constructors ////// Constructor. If closeBamlStream is true, then the parser is the owner of the /// owner of the stream, and will close the stream when finished parsing. /// internal TreeBuilderBamlTranslator( Stream bamlStream, ParserContext parserContext, object parent, bool closeBamlStream) : base() { _bamlStream = bamlStream; _closeBamlStream = closeBamlStream; Debug.Assert(null != parserContext.XamlTypeMapper); RecordReader = new BamlRecordReader(bamlStream, parserContext, parent); } // internal constructor to allow subclassing. internal TreeBuilderBamlTranslator() { } #endregion Constructors #region Overrides ////// Internal Avalon method. Used to parse a BAML file. /// ///An array containing the root objects in the BAML stream public override object ParseFragment() { bool asyncParse = false; // only close stream if not in Async parse mode. try { RecordReader.Initialize(); RecordReader.ReadVersionHeader(); // if baml, read the start document and get the ParseMode. // Review, should probably be done in Parse() BamlRecordType recType = (BamlRecordType)RecordReader.BinaryReader.ReadByte(); if (recType != BamlRecordType.DocumentStart) { throw new InvalidOperationException(); } BamlRecord bamlRecord = RecordReader.BamlRecordManager.ReadNextRecord( RecordReader.BinaryReader, Int64.MaxValue, recType); Debug.Assert(null != bamlRecord); Debug.Assert(bamlRecord.RecordType == BamlRecordType.DocumentStart); BamlDocumentStartRecord bamlStartDoc = bamlRecord as BamlDocumentStartRecord; if (null != bamlStartDoc) { // SetParse Mode may have already change the ParseMode so // only use what is in the record if still Uninitialized. if ( XamlParseMode == XamlParseMode.Uninitialized ) { #if SUPPORTBAMLASYNC // For M11 we will not support async loading of baml files. They // will all be treated as synchronous. This is done to reduce // surface area, as described in windows bug # 1079575 if (bamlStartDoc.LoadAsync) { XamlParseMode = XamlParseMode.Asynchronous; } else #endif { XamlParseMode = XamlParseMode.Synchronous; } } MaxAsyncRecords = bamlStartDoc.MaxAsyncRecords; } // Set associated record reader async info to what has been found so far RecordReader.XamlParseMode = XamlParseMode; RecordReader.MaxAsyncRecords = MaxAsyncRecords; RecordReader.IsDebugBamlStream = bamlStartDoc.DebugBaml; Debug.Assert(XamlParseMode != XamlParseMode.Uninitialized); // if in synchronous mode then just read the baml stream and then // return. if going into async mode then build up the first tag // synchronously and then post a queue item. // Note that we don't actually go into async mode for compiling. if (XamlParseMode == XamlParseMode.Synchronous) { RecordReader.Read(); TreeBuildComplete(); //Debug.Assert(1 >= RootList.Count, "Cannot have multiple root elements in BAML stream"); } else { // read in the first record since binder at present // needs this. bool moreData = true; // sit in synchronous read until get first root. Need this // until we get async binder support. while (GetRoot() == null && moreData) { moreData = RecordReader.Read(true /* single record mode*/); } if (moreData && GetRoot() == null) { // before going async want to switch to async stream interfaces // so we don't block on I/O. // setup stream Manager on Reader and kick of Async Writes StreamManager = new ReadWriteStreamManager(); // RecordReader no points to the ReaderWriter stream which // is different from our BAMLStream member. RecordReader.BamlStream = StreamManager.ReaderStream; // now spin a thread to read the BAML. This can change // once we get Read support that fails if contents isn't // available instead of blocks. asyncParse = true; ThreadStart threadStart = new ThreadStart(ReadBamlAsync); Thread thread = new Thread(threadStart); thread.Start(); // post a work item to do the rest. Post(); } else { // if don't get a root or there isn't any moredata then // we are done building. TreeBuildComplete(); } } } finally { // If not in an async parse and we are told to close the // stream explicitly, then we are done with the input stream. // Otherwise rely on the async thread calling Close if (!asyncParse) { CloseBamlInputStream(); } } return GetRoot(); } ////// called when TreeBuilder gets an Async slice /// we override the base class to see if can close the input stream. /// internal override void HandleAsyncQueueItem() { if (DoneReadingBamlStream) { CloseBamlInputStream(); } base.HandleAsyncQueueItem(); } #endregion overrides #region Methods // Async callback that reads the next chunk from the baml stream, until the // end of the stream has been reached, or we've read a certain number of // records. protected void ReadBamlAsync() { try { // sits in a loop reading BAML // hopefully temporary function not needed when can get read to // just fail if number of requested bytes are not yet available. Debug.Assert(null != StreamManager,"StreamManager is null in Async Read"); Debug.Assert(BamlStream != RecordReader.BamlStream,"Input BAML shouldn't be same as Output"); WriterStream writerStream = StreamManager.WriterStream; int bytesRead; long writtenStreamLength = 0; int maxBufferSize = 256; // for now read 256 at a time. byte[] buffer = new byte[maxBufferSize]; while (!DoneReadingBamlStream) { bytesRead = BamlStream.Read(buffer,0,maxBufferSize); if (0 == bytesRead) { DoneReadingBamlStream = true; } else { writerStream.Write(buffer,0,bytesRead); writtenStreamLength += bytesRead; writerStream.UpdateReaderLength(writtenStreamLength); } } } catch (Exception e) { if (CriticalExceptions.IsCriticalException(e)) { throw; } else { // catch any exception on the async thread and send it over. // make sure you set the exception before the error flag. ParseException = e; } } } ////// Helper Function to close the BamlInputStream. /// This can get called twice in Async, once the first time we /// get on the UI thread after done reading input and second when /// the tree buildComplete occurs so check for NULL /// the queue /// void CloseBamlInputStream() { // possible we have to close // In the straight BamlLoad case we will have a BamlStream to Close // if we are given ownership of the BamlStream in BuildFromBaml. if (null != BamlStream ) { if (_closeBamlStream) { BamlStream.Close(); } // even if we don't own the treat set the member to null _bamlStream = null; } } #endregion Methods #region Properties ////// BamlStream to load from /// protected Stream BamlStream { get { return _bamlStream; } set { _bamlStream = value; } } ////// flag used in Async read sets to true when /// BamlStream has been completely read. /// protected bool DoneReadingBamlStream { get { return _doneReadingBamlStream; } set { _doneReadingBamlStream = value; } } ////// ReaderWriterStream used if we kick off an Async Load. /// protected ReadWriteStreamManager StreamManager { get { return _streamManager; } set { _streamManager = value; } } #endregion Properties #region Data // Manager used to handle the stream operations. ReadWriteStreamManager _streamManager; // Stream of baml records. Stream _bamlStream; // True if the parser owns the baml stream, and can close the stream // when the parse is complete. False if the stream is owned by someone // else, in which case the parser will not close it. bool _closeBamlStream; // True when baml stream has completed reading in async mode. bool _doneReadingBamlStream; #endregion Data #endif // !PBTCOMPILER } } // 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
- Bitmap.cs
- DataGridColumnsPage.cs
- WsdlExporter.cs
- PlaceHolder.cs
- MutexSecurity.cs
- DataServiceConfiguration.cs
- ObjectIDGenerator.cs
- SamlSerializer.cs
- AccessDataSource.cs
- ColorTransform.cs
- XpsSerializerFactory.cs
- DataControlFieldCell.cs
- XamlLoadErrorInfo.cs
- WindowsButton.cs
- SelectorItemAutomationPeer.cs
- ItemTypeToolStripMenuItem.cs
- BooleanSwitch.cs
- TagMapCollection.cs
- PropertyConverter.cs
- RequestCachingSection.cs
- SourceSwitch.cs
- DataSourceXmlAttributeAttribute.cs
- VectorAnimation.cs
- PanningMessageFilter.cs
- SmtpDigestAuthenticationModule.cs
- CompositeTypefaceMetrics.cs
- HttpCapabilitiesSectionHandler.cs
- SharedPerformanceCounter.cs
- TextFormattingConverter.cs
- XmlIncludeAttribute.cs
- SQLInt64.cs
- ClientRoleProvider.cs
- StreamWriter.cs
- StackBuilderSink.cs
- LocatorBase.cs
- ArithmeticLiteral.cs
- SetterBase.cs
- DoubleCollectionValueSerializer.cs
- MembershipPasswordException.cs
- RC2.cs
- StandardBindingReliableSessionElement.cs
- InvalidateEvent.cs
- securitycriticaldataClass.cs
- WindowsListViewItem.cs
- SerializationEventsCache.cs
- ExpressionBindings.cs
- HttpCookieCollection.cs
- Page.cs
- MembershipPasswordException.cs
- HostingEnvironmentSection.cs
- FontFamilyConverter.cs
- ConnectionProviderAttribute.cs
- WebRequestModuleElement.cs
- DayRenderEvent.cs
- IDataContractSurrogate.cs
- TypeSystemProvider.cs
- ArrayElementGridEntry.cs
- KeysConverter.cs
- CatalogZone.cs
- MemoryRecordBuffer.cs
- LocatorManager.cs
- DefaultValueAttribute.cs
- Binding.cs
- XdrBuilder.cs
- HttpCachePolicyWrapper.cs
- XmlSchemaComplexContentExtension.cs
- FlowDocumentPage.cs
- SecUtil.cs
- NamedPipeTransportManager.cs
- XPathEmptyIterator.cs
- InternalUserCancelledException.cs
- ScrollPatternIdentifiers.cs
- Part.cs
- IdnMapping.cs
- UnionCodeGroup.cs
- ScriptRegistrationManager.cs
- XmlSchemaSimpleContent.cs
- JumpTask.cs
- BitmapFrameEncode.cs
- HandleCollector.cs
- TextServicesCompartment.cs
- EditCommandColumn.cs
- XmlMemberMapping.cs
- LogStore.cs
- RelationshipEnd.cs
- EventMap.cs
- MouseButton.cs
- DbConnectionOptions.cs
- SingleObjectCollection.cs
- GetMemberBinder.cs
- EpmCustomContentWriterNodeData.cs
- XmlMtomReader.cs
- IssuedTokenClientBehaviorsElementCollection.cs
- ExpressionHelper.cs
- CodeArrayCreateExpression.cs
- AddInPipelineAttributes.cs
- EditorPartCollection.cs
- BuildManagerHost.cs
- TraceFilter.cs
- GridViewRowCollection.cs