Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / Xml / System / Xml / Dom / XmlElementList.cs / 1 / XmlElementList.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace System.Xml {
using System;
using System.Collections;
using System.Diagnostics;
internal class XmlElementList: XmlNodeList {
string asterisk;
int changeCount; //recording the total number that the dom tree has been changed ( insertion and deletetion )
//the member vars below are saved for further reconstruction
string name; //only one of 2 string groups will be initialized depends on which constructor is called.
string localName;
string namespaceURI;
XmlNode rootNode;
// the memeber vars belwo serves the optimization of accessing of the elements in the list
int curInd; // -1 means the starting point for a new search round
XmlNode curElem; // if sets to rootNode, means the starting point for a new search round
bool empty; // whether the list is empty
bool atomized; //whether the localname and namespaceuri are aomized
int matchCount; // cached list count. -1 means it needs reconstruction
private XmlElementList( XmlNode parent) {
Debug.Assert ( parent != null );
Debug.Assert( parent.NodeType == XmlNodeType.Element || parent.NodeType == XmlNodeType.Document );
this.rootNode = parent;
Debug.Assert( parent.Document != null );
this.curInd = -1;
this.curElem = rootNode;
this.changeCount = 0;
this.empty = false;
this.atomized = true;
this.matchCount = -1;
new XmlElementListListener(parent.Document, this);
}
internal void ConcurrencyCheck(XmlNodeChangedEventArgs args){
if( atomized == false ) {
XmlNameTable nameTable = this.rootNode.Document.NameTable;
this.localName = nameTable.Add( this.localName );
this.namespaceURI = nameTable.Add( this.namespaceURI );
this.atomized = true;
}
if ( IsMatch( args.Node ) ) {
this.changeCount++ ;
this.curInd = -1;
this.curElem = rootNode;
if( args.Action == XmlNodeChangedAction.Insert )
this.empty = false;
}
this.matchCount = -1;
}
internal XmlElementList( XmlNode parent, string name ): this( parent ) {
Debug.Assert( parent.Document != null );
XmlNameTable nt = parent.Document.NameTable;
Debug.Assert( nt != null );
asterisk = nt.Add("*");
this.name = nt.Add( name );
this.localName = null;
this.namespaceURI = null;
}
internal XmlElementList( XmlNode parent, string localName, string namespaceURI ): this( parent ) {
Debug.Assert( parent.Document != null );
XmlNameTable nt = parent.Document.NameTable;
Debug.Assert( nt != null );
asterisk = nt.Add("*");
this.localName = nt.Get( localName );
this.namespaceURI = nt.Get( namespaceURI );
if( (this.localName == null) || (this.namespaceURI== null) ) {
this.empty = true;
this.atomized = false;
this.localName = localName;
this.namespaceURI = namespaceURI;
}
this.name = null;
}
internal int ChangeCount {
get { return changeCount; }
}
// return the next element node that is in PreOrder
private XmlNode NextElemInPreOrder( XmlNode curNode ) {
Debug.Assert( curNode != null );
//For preorder walking, first try its child
XmlNode retNode = curNode.FirstChild;
if ( retNode == null ) {
//if no child, the next node forward will the be the NextSibling of the first ancestor which has NextSibling
//so, first while-loop find out such an ancestor (until no more ancestor or the ancestor is the rootNode
retNode = curNode;
while ( retNode != null
&& retNode != rootNode
&& retNode.NextSibling == null ) {
retNode = retNode.ParentNode;
}
//then if such ancestor exists, set the retNode to its NextSibling
if ( retNode != null && retNode != rootNode )
retNode = retNode.NextSibling;
}
if ( retNode == this.rootNode )
//if reach the rootNode, consider having walked through the whole tree and no more element after the curNode
retNode = null;
return retNode;
}
// return the previous element node that is in PreOrder
private XmlNode PrevElemInPreOrder( XmlNode curNode ) {
Debug.Assert( curNode != null );
//For preorder walking, the previous node will be the right-most node in the tree of PreviousSibling of the curNode
XmlNode retNode = curNode.PreviousSibling;
// so if the PreviousSibling is not null, going through the tree down to find the right-most node
while ( retNode != null ) {
if ( retNode.LastChild == null )
break;
retNode = retNode.LastChild;
}
// if no PreviousSibling, the previous node will be the curNode's parentNode
if ( retNode == null )
retNode = curNode.ParentNode;
// if the final retNode is rootNode, consider having walked through the tree and no more previous node
if ( retNode == this.rootNode )
retNode = null;
return retNode;
}
// if the current node a matching element node
private bool IsMatch ( XmlNode curNode ) {
if (curNode.NodeType == XmlNodeType.Element) {
if ( this.name != null ) {
if ( Ref.Equal(this.name, asterisk) || Ref.Equal(curNode.Name, this.name) )
return true;
}
else {
if (
(Ref.Equal(this.localName, asterisk) || Ref.Equal(curNode.LocalName, this.localName) ) &&
(Ref.Equal(this.namespaceURI, asterisk) || curNode.NamespaceURI == this.namespaceURI )
) {
return true;
}
}
}
return false;
}
private XmlNode GetMatchingNode( XmlNode n, bool bNext ) {
Debug.Assert( n!= null );
XmlNode node = n;
do {
if ( bNext )
node = NextElemInPreOrder( node );
else
node = PrevElemInPreOrder( node );
} while ( node != null && !IsMatch( node ) );
return node;
}
private XmlNode GetNthMatchingNode( XmlNode n, bool bNext, int nCount ) {
Debug.Assert( n!= null );
XmlNode node = n;
for ( int ind = 0 ; ind < nCount; ind++ ) {
node = GetMatchingNode( node, bNext );
if ( node == null )
return null;
}
return node;
}
//the function is for the enumerator to find out the next available matching element node
public XmlNode GetNextNode( XmlNode n ) {
if( this.empty == true )
return null;
XmlNode node = ( n == null ) ? rootNode : n;
return GetMatchingNode( node, true );
}
public override XmlNode Item(int index) {
if ( rootNode == null || index < 0 )
return null;
if( this.empty == true )
return null;
if ( curInd == index )
return curElem;
int nDiff = index - curInd;
bool bForward = ( nDiff > 0 );
if ( nDiff < 0 )
nDiff = -nDiff;
XmlNode node;
if ( ( node = GetNthMatchingNode( curElem, bForward, nDiff ) ) != null ) {
curInd = index;
curElem = node;
return curElem;
}
return null;
}
public override int Count {
get {
if( this.empty == true )
return 0;
if (this.matchCount < 0) {
int currMatchCount = 0;
int currChangeCount = this.changeCount;
XmlNode node = rootNode;
while ((node = GetMatchingNode(node, true)) != null) {
currMatchCount++;
}
if (currChangeCount != this.changeCount) {
return currMatchCount;
}
this.matchCount = currMatchCount;
}
return this.matchCount;
}
}
public override IEnumerator GetEnumerator() {
if( this.empty == true )
return new XmlEmptyElementListEnumerator(this);;
return new XmlElementListEnumerator(this);
}
}
internal class XmlElementListEnumerator : IEnumerator {
XmlElementList list;
XmlNode curElem;
int changeCount; //save the total number that the dom tree has been changed ( insertion and deletetion ) when this enumerator is created
public XmlElementListEnumerator( XmlElementList list ) {
this.list = list;
this.curElem = null;
this.changeCount = list.ChangeCount;
}
public bool MoveNext() {
if ( list.ChangeCount != this.changeCount ) {
//the number mismatch, there is new change(s) happened since last MoveNext() is called.
throw new InvalidOperationException( Res.GetString(Res.Xdom_Enum_ElementList) );
}
else {
curElem = list.GetNextNode( curElem );
}
return curElem != null;
}
public void Reset() {
curElem = null;
//reset the number of changes to be synced with current dom tree as well
this.changeCount = list.ChangeCount;
}
public object Current {
get { return curElem; }
}
}
internal class XmlEmptyElementListEnumerator : IEnumerator {
public XmlEmptyElementListEnumerator( XmlElementList list ) {
}
public bool MoveNext() {
return false;
}
public void Reset() {
}
public object Current {
get { return null; }
}
}
internal class XmlElementListListener {
WeakReference elemList;
XmlDocument doc;
XmlNodeChangedEventHandler nodeChangeHandler = null;
internal XmlElementListListener(XmlDocument doc, XmlElementList elemList) {
this.doc = doc;
this.elemList = new WeakReference(elemList);
this.nodeChangeHandler = new XmlNodeChangedEventHandler( this.OnListChanged );
doc.NodeInserted += this.nodeChangeHandler;
doc.NodeRemoved += this.nodeChangeHandler;
}
private void OnListChanged( object sender, XmlNodeChangedEventArgs args ) {
XmlElementList elemList = (XmlElementList)this.elemList.Target;
if (null != elemList) {
elemList.ConcurrencyCheck(args);
} else {
this.doc.NodeInserted -= this.nodeChangeHandler;
this.doc.NodeRemoved -= this.nodeChangeHandler;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace System.Xml {
using System;
using System.Collections;
using System.Diagnostics;
internal class XmlElementList: XmlNodeList {
string asterisk;
int changeCount; //recording the total number that the dom tree has been changed ( insertion and deletetion )
//the member vars below are saved for further reconstruction
string name; //only one of 2 string groups will be initialized depends on which constructor is called.
string localName;
string namespaceURI;
XmlNode rootNode;
// the memeber vars belwo serves the optimization of accessing of the elements in the list
int curInd; // -1 means the starting point for a new search round
XmlNode curElem; // if sets to rootNode, means the starting point for a new search round
bool empty; // whether the list is empty
bool atomized; //whether the localname and namespaceuri are aomized
int matchCount; // cached list count. -1 means it needs reconstruction
private XmlElementList( XmlNode parent) {
Debug.Assert ( parent != null );
Debug.Assert( parent.NodeType == XmlNodeType.Element || parent.NodeType == XmlNodeType.Document );
this.rootNode = parent;
Debug.Assert( parent.Document != null );
this.curInd = -1;
this.curElem = rootNode;
this.changeCount = 0;
this.empty = false;
this.atomized = true;
this.matchCount = -1;
new XmlElementListListener(parent.Document, this);
}
internal void ConcurrencyCheck(XmlNodeChangedEventArgs args){
if( atomized == false ) {
XmlNameTable nameTable = this.rootNode.Document.NameTable;
this.localName = nameTable.Add( this.localName );
this.namespaceURI = nameTable.Add( this.namespaceURI );
this.atomized = true;
}
if ( IsMatch( args.Node ) ) {
this.changeCount++ ;
this.curInd = -1;
this.curElem = rootNode;
if( args.Action == XmlNodeChangedAction.Insert )
this.empty = false;
}
this.matchCount = -1;
}
internal XmlElementList( XmlNode parent, string name ): this( parent ) {
Debug.Assert( parent.Document != null );
XmlNameTable nt = parent.Document.NameTable;
Debug.Assert( nt != null );
asterisk = nt.Add("*");
this.name = nt.Add( name );
this.localName = null;
this.namespaceURI = null;
}
internal XmlElementList( XmlNode parent, string localName, string namespaceURI ): this( parent ) {
Debug.Assert( parent.Document != null );
XmlNameTable nt = parent.Document.NameTable;
Debug.Assert( nt != null );
asterisk = nt.Add("*");
this.localName = nt.Get( localName );
this.namespaceURI = nt.Get( namespaceURI );
if( (this.localName == null) || (this.namespaceURI== null) ) {
this.empty = true;
this.atomized = false;
this.localName = localName;
this.namespaceURI = namespaceURI;
}
this.name = null;
}
internal int ChangeCount {
get { return changeCount; }
}
// return the next element node that is in PreOrder
private XmlNode NextElemInPreOrder( XmlNode curNode ) {
Debug.Assert( curNode != null );
//For preorder walking, first try its child
XmlNode retNode = curNode.FirstChild;
if ( retNode == null ) {
//if no child, the next node forward will the be the NextSibling of the first ancestor which has NextSibling
//so, first while-loop find out such an ancestor (until no more ancestor or the ancestor is the rootNode
retNode = curNode;
while ( retNode != null
&& retNode != rootNode
&& retNode.NextSibling == null ) {
retNode = retNode.ParentNode;
}
//then if such ancestor exists, set the retNode to its NextSibling
if ( retNode != null && retNode != rootNode )
retNode = retNode.NextSibling;
}
if ( retNode == this.rootNode )
//if reach the rootNode, consider having walked through the whole tree and no more element after the curNode
retNode = null;
return retNode;
}
// return the previous element node that is in PreOrder
private XmlNode PrevElemInPreOrder( XmlNode curNode ) {
Debug.Assert( curNode != null );
//For preorder walking, the previous node will be the right-most node in the tree of PreviousSibling of the curNode
XmlNode retNode = curNode.PreviousSibling;
// so if the PreviousSibling is not null, going through the tree down to find the right-most node
while ( retNode != null ) {
if ( retNode.LastChild == null )
break;
retNode = retNode.LastChild;
}
// if no PreviousSibling, the previous node will be the curNode's parentNode
if ( retNode == null )
retNode = curNode.ParentNode;
// if the final retNode is rootNode, consider having walked through the tree and no more previous node
if ( retNode == this.rootNode )
retNode = null;
return retNode;
}
// if the current node a matching element node
private bool IsMatch ( XmlNode curNode ) {
if (curNode.NodeType == XmlNodeType.Element) {
if ( this.name != null ) {
if ( Ref.Equal(this.name, asterisk) || Ref.Equal(curNode.Name, this.name) )
return true;
}
else {
if (
(Ref.Equal(this.localName, asterisk) || Ref.Equal(curNode.LocalName, this.localName) ) &&
(Ref.Equal(this.namespaceURI, asterisk) || curNode.NamespaceURI == this.namespaceURI )
) {
return true;
}
}
}
return false;
}
private XmlNode GetMatchingNode( XmlNode n, bool bNext ) {
Debug.Assert( n!= null );
XmlNode node = n;
do {
if ( bNext )
node = NextElemInPreOrder( node );
else
node = PrevElemInPreOrder( node );
} while ( node != null && !IsMatch( node ) );
return node;
}
private XmlNode GetNthMatchingNode( XmlNode n, bool bNext, int nCount ) {
Debug.Assert( n!= null );
XmlNode node = n;
for ( int ind = 0 ; ind < nCount; ind++ ) {
node = GetMatchingNode( node, bNext );
if ( node == null )
return null;
}
return node;
}
//the function is for the enumerator to find out the next available matching element node
public XmlNode GetNextNode( XmlNode n ) {
if( this.empty == true )
return null;
XmlNode node = ( n == null ) ? rootNode : n;
return GetMatchingNode( node, true );
}
public override XmlNode Item(int index) {
if ( rootNode == null || index < 0 )
return null;
if( this.empty == true )
return null;
if ( curInd == index )
return curElem;
int nDiff = index - curInd;
bool bForward = ( nDiff > 0 );
if ( nDiff < 0 )
nDiff = -nDiff;
XmlNode node;
if ( ( node = GetNthMatchingNode( curElem, bForward, nDiff ) ) != null ) {
curInd = index;
curElem = node;
return curElem;
}
return null;
}
public override int Count {
get {
if( this.empty == true )
return 0;
if (this.matchCount < 0) {
int currMatchCount = 0;
int currChangeCount = this.changeCount;
XmlNode node = rootNode;
while ((node = GetMatchingNode(node, true)) != null) {
currMatchCount++;
}
if (currChangeCount != this.changeCount) {
return currMatchCount;
}
this.matchCount = currMatchCount;
}
return this.matchCount;
}
}
public override IEnumerator GetEnumerator() {
if( this.empty == true )
return new XmlEmptyElementListEnumerator(this);;
return new XmlElementListEnumerator(this);
}
}
internal class XmlElementListEnumerator : IEnumerator {
XmlElementList list;
XmlNode curElem;
int changeCount; //save the total number that the dom tree has been changed ( insertion and deletetion ) when this enumerator is created
public XmlElementListEnumerator( XmlElementList list ) {
this.list = list;
this.curElem = null;
this.changeCount = list.ChangeCount;
}
public bool MoveNext() {
if ( list.ChangeCount != this.changeCount ) {
//the number mismatch, there is new change(s) happened since last MoveNext() is called.
throw new InvalidOperationException( Res.GetString(Res.Xdom_Enum_ElementList) );
}
else {
curElem = list.GetNextNode( curElem );
}
return curElem != null;
}
public void Reset() {
curElem = null;
//reset the number of changes to be synced with current dom tree as well
this.changeCount = list.ChangeCount;
}
public object Current {
get { return curElem; }
}
}
internal class XmlEmptyElementListEnumerator : IEnumerator {
public XmlEmptyElementListEnumerator( XmlElementList list ) {
}
public bool MoveNext() {
return false;
}
public void Reset() {
}
public object Current {
get { return null; }
}
}
internal class XmlElementListListener {
WeakReference elemList;
XmlDocument doc;
XmlNodeChangedEventHandler nodeChangeHandler = null;
internal XmlElementListListener(XmlDocument doc, XmlElementList elemList) {
this.doc = doc;
this.elemList = new WeakReference(elemList);
this.nodeChangeHandler = new XmlNodeChangedEventHandler( this.OnListChanged );
doc.NodeInserted += this.nodeChangeHandler;
doc.NodeRemoved += this.nodeChangeHandler;
}
private void OnListChanged( object sender, XmlNodeChangedEventArgs args ) {
XmlElementList elemList = (XmlElementList)this.elemList.Target;
if (null != elemList) {
elemList.ConcurrencyCheck(args);
} else {
this.doc.NodeInserted -= this.nodeChangeHandler;
this.doc.NodeRemoved -= this.nodeChangeHandler;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExtendedTransformFactory.cs
- ToolboxComponentsCreatingEventArgs.cs
- RequestQueue.cs
- TextElement.cs
- SqlExpander.cs
- RowsCopiedEventArgs.cs
- ResourceReader.cs
- DropDownList.cs
- DataTableNameHandler.cs
- FloaterBaseParaClient.cs
- PageAsyncTaskManager.cs
- odbcmetadatafactory.cs
- IPEndPointCollection.cs
- ButtonBase.cs
- StorageAssociationTypeMapping.cs
- ApplicationId.cs
- ExpressionBuilder.cs
- WindowClosedEventArgs.cs
- EventLogInformation.cs
- JsonQueryStringConverter.cs
- BaseValidator.cs
- SqlInternalConnectionTds.cs
- SiteMapNode.cs
- FreeFormDragDropManager.cs
- ModulesEntry.cs
- TextModifierScope.cs
- DataPointer.cs
- ReadWriteObjectLock.cs
- WebBrowsableAttribute.cs
- TypeUtils.cs
- Converter.cs
- JoinElimination.cs
- IndentedWriter.cs
- DependencyPropertyDescriptor.cs
- AppDomainShutdownMonitor.cs
- DynamicVirtualDiscoSearcher.cs
- ImmutableObjectAttribute.cs
- DecoderNLS.cs
- UniqueTransportManagerRegistration.cs
- PolicyLevel.cs
- SessionSwitchEventArgs.cs
- controlskin.cs
- HTMLTagNameToTypeMapper.cs
- CodeNamespace.cs
- Assembly.cs
- ObjectHandle.cs
- CollectionView.cs
- SpellerStatusTable.cs
- Point3DCollectionConverter.cs
- SaveFileDialog.cs
- XmlCustomFormatter.cs
- WebControlsSection.cs
- Base64Encoder.cs
- RightsManagementLicense.cs
- XmlArrayAttribute.cs
- ParameterCollection.cs
- SignedXml.cs
- RoutedPropertyChangedEventArgs.cs
- PropertyManager.cs
- XmlSchemaValidationException.cs
- XmlEntity.cs
- ListBox.cs
- DataGridSortCommandEventArgs.cs
- BasicExpressionVisitor.cs
- ExpressionBindingCollection.cs
- Message.cs
- SchemaCollectionCompiler.cs
- CheckBoxAutomationPeer.cs
- ValidationVisibilityAttribute.cs
- CharEntityEncoderFallback.cs
- EntityConnectionStringBuilderItem.cs
- SelectionItemProviderWrapper.cs
- PageCache.cs
- ControlUtil.cs
- Stack.cs
- PersonalizationAdministration.cs
- ProviderUtil.cs
- WindowClosedEventArgs.cs
- GradientBrush.cs
- InfoCardRSAPKCS1KeyExchangeDeformatter.cs
- HttpRequest.cs
- DiagnosticsConfiguration.cs
- _SingleItemRequestCache.cs
- HandlerBase.cs
- MouseGestureConverter.cs
- SafeLocalMemHandle.cs
- MimeTypeMapper.cs
- BitmapImage.cs
- ComboBoxItem.cs
- PageStatePersister.cs
- ActivityExecutorSurrogate.cs
- VoiceObjectToken.cs
- CannotUnloadAppDomainException.cs
- Catch.cs
- CloudCollection.cs
- ExpressionLexer.cs
- OutputCacheProfileCollection.cs
- Label.cs
- AppSettingsSection.cs
- ECDsa.cs