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
- ContextProperty.cs
- Label.cs
- activationcontext.cs
- PropertyValue.cs
- ResourceExpressionBuilder.cs
- PropertiesTab.cs
- SimpleTextLine.cs
- Messages.cs
- ChangesetResponse.cs
- cryptoapiTransform.cs
- ItemContainerGenerator.cs
- SplineKeyFrames.cs
- ObjectDataSourceStatusEventArgs.cs
- DataServiceContext.cs
- NavigationPropertyEmitter.cs
- CachedPathData.cs
- RequestTimeoutManager.cs
- ExpressionBinding.cs
- ReliabilityContractAttribute.cs
- WindowsListBox.cs
- ActiveXHost.cs
- CommonXSendMessage.cs
- FileSecurity.cs
- CompiledAction.cs
- HttpContext.cs
- AssertFilter.cs
- TextEditorSelection.cs
- PropertyKey.cs
- ResXResourceReader.cs
- AnnotationHelper.cs
- PropertyEmitter.cs
- HandlerMappingMemo.cs
- ConfigurationPermission.cs
- TdsRecordBufferSetter.cs
- RtfToken.cs
- ValidationError.cs
- BaseProcessor.cs
- ConfigurationManager.cs
- SchemaImporterExtensionElement.cs
- WorkflowTransactionOptions.cs
- ArraySubsetEnumerator.cs
- Item.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- UrlMappingsModule.cs
- XmlSerializationGeneratedCode.cs
- MonitorWrapper.cs
- SQLByte.cs
- EdgeProfileValidation.cs
- ResourceContainer.cs
- SettingsPropertyValueCollection.cs
- BindingNavigator.cs
- ReadContentAsBinaryHelper.cs
- URI.cs
- FloatUtil.cs
- CrossContextChannel.cs
- WebAdminConfigurationHelper.cs
- MatrixStack.cs
- DesignTimeTemplateParser.cs
- SafePointer.cs
- TextTreeText.cs
- Hyperlink.cs
- MultiView.cs
- SchemaImporterExtensionElement.cs
- ExtentKey.cs
- ConnectionString.cs
- EnumConverter.cs
- FileStream.cs
- PauseStoryboard.cs
- MetadataSection.cs
- DisposableCollectionWrapper.cs
- CommunicationObjectManager.cs
- JulianCalendar.cs
- CodeArrayCreateExpression.cs
- DataGridViewDataErrorEventArgs.cs
- Brush.cs
- GestureRecognizer.cs
- VirtualizingStackPanel.cs
- XmlILStorageConverter.cs
- DataServiceExpressionVisitor.cs
- SQLMembershipProvider.cs
- XmlWrappingReader.cs
- AmbientProperties.cs
- SqlRemoveConstantOrderBy.cs
- Splitter.cs
- MessageQueuePermissionEntryCollection.cs
- PathFigureCollectionConverter.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- ComponentCollection.cs
- TextRunCacheImp.cs
- OneOfScalarConst.cs
- CodeSnippetStatement.cs
- SynchronizationContext.cs
- InkPresenterAutomationPeer.cs
- WorkflowTerminatedException.cs
- ListBox.cs
- SSmlParser.cs
- DataExchangeServiceBinder.cs
- WinFormsComponentEditor.cs
- AsyncOperationLifetimeManager.cs
- ComplexTypeEmitter.cs