You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,331 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="XmlBoundElement.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="false" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument
|
||||
namespace System.Xml {
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
|
||||
internal enum ElementState {
|
||||
None,
|
||||
Defoliated,
|
||||
WeakFoliation,
|
||||
StrongFoliation,
|
||||
Foliating,
|
||||
Defoliating,
|
||||
}
|
||||
|
||||
internal sealed class XmlBoundElement: XmlElement {
|
||||
private DataRow row;
|
||||
private ElementState state;
|
||||
|
||||
internal XmlBoundElement( string prefix, string localName, string namespaceURI, XmlDocument doc )
|
||||
: base( prefix, localName, namespaceURI, doc ) {
|
||||
state = ElementState.None;
|
||||
}
|
||||
|
||||
public override XmlAttributeCollection Attributes {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.Attributes;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasAttributes {
|
||||
get { return Attributes.Count > 0; }
|
||||
}
|
||||
|
||||
public override XmlNode FirstChild {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.FirstChild;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlNode SafeFirstChild { get { return base.FirstChild; } }
|
||||
|
||||
public override XmlNode LastChild {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.LastChild;
|
||||
}
|
||||
}
|
||||
|
||||
public override XmlNode PreviousSibling {
|
||||
get {
|
||||
XmlNode prev = base.PreviousSibling;
|
||||
if ( prev == null ) {
|
||||
XmlBoundElement parent = ParentNode as XmlBoundElement;
|
||||
if ( parent != null ) {
|
||||
parent.AutoFoliate();
|
||||
return base.PreviousSibling;
|
||||
}
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlNode SafePreviousSibling { get { return base.PreviousSibling; } }
|
||||
|
||||
public override XmlNode NextSibling {
|
||||
get {
|
||||
XmlNode next = base.NextSibling;
|
||||
if ( next == null ) {
|
||||
XmlBoundElement parent = ParentNode as XmlBoundElement;
|
||||
if ( parent != null ) {
|
||||
parent.AutoFoliate();
|
||||
return base.NextSibling;
|
||||
}
|
||||
}
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlNode SafeNextSibling { get { return base.NextSibling; } }
|
||||
|
||||
public override bool HasChildNodes {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.HasChildNodes;
|
||||
}
|
||||
}
|
||||
|
||||
public override XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) {
|
||||
AutoFoliate();
|
||||
return base.InsertBefore( newChild, refChild );
|
||||
}
|
||||
|
||||
public override XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) {
|
||||
AutoFoliate();
|
||||
return base.InsertAfter( newChild, refChild );
|
||||
}
|
||||
|
||||
public override XmlNode ReplaceChild(XmlNode newChild, XmlNode oldChild) {
|
||||
AutoFoliate();
|
||||
return base.ReplaceChild( newChild, oldChild );
|
||||
}
|
||||
|
||||
public override XmlNode AppendChild(XmlNode newChild) {
|
||||
AutoFoliate();
|
||||
return base.AppendChild( newChild );
|
||||
}
|
||||
|
||||
internal void RemoveAllChildren() {
|
||||
XmlNode child = FirstChild;
|
||||
XmlNode sibling = null;
|
||||
|
||||
while ( child != null ) {
|
||||
sibling = child.NextSibling;
|
||||
RemoveChild( child );
|
||||
child = sibling;
|
||||
}
|
||||
}
|
||||
|
||||
public override string InnerXml {
|
||||
get {
|
||||
return base.InnerXml;
|
||||
}
|
||||
set {
|
||||
|
||||
RemoveAllChildren();
|
||||
|
||||
XmlDataDocument doc = (XmlDataDocument) OwnerDocument;
|
||||
|
||||
bool bOrigIgnoreXmlEvents = doc.IgnoreXmlEvents;
|
||||
bool bOrigIgnoreDataSetEvents = doc.IgnoreDataSetEvents;
|
||||
|
||||
doc.IgnoreXmlEvents = true;
|
||||
doc.IgnoreDataSetEvents = true;
|
||||
|
||||
base.InnerXml = value;
|
||||
|
||||
doc.SyncTree( this );
|
||||
|
||||
doc.IgnoreDataSetEvents = bOrigIgnoreDataSetEvents;
|
||||
doc.IgnoreXmlEvents = bOrigIgnoreXmlEvents;
|
||||
}
|
||||
}
|
||||
|
||||
internal DataRow Row {
|
||||
get { return row;}
|
||||
set { row = value;}
|
||||
}
|
||||
|
||||
internal bool IsFoliated {
|
||||
get {
|
||||
while ( state == ElementState.Foliating || state == ElementState.Defoliating )
|
||||
System.Threading.Thread.Sleep(0);
|
||||
//has to be sure that we are either foliated or defoliated when ask for IsFoliated.
|
||||
return state != ElementState.Defoliated;
|
||||
}
|
||||
}
|
||||
|
||||
internal ElementState ElementState {
|
||||
get { return state;}
|
||||
set { state = value;}
|
||||
}
|
||||
|
||||
internal void Foliate( ElementState newState ) {
|
||||
XmlDataDocument doc = (XmlDataDocument) OwnerDocument;
|
||||
if ( doc != null )
|
||||
doc.Foliate( this, newState );
|
||||
}
|
||||
|
||||
// Foliate the node as a side effect of user calling functions on this node (like NextSibling) OR as a side effect of DataDocNav using nodes to do editing
|
||||
private void AutoFoliate() {
|
||||
XmlDataDocument doc = (XmlDataDocument) OwnerDocument;
|
||||
if ( doc != null )
|
||||
doc.Foliate( this, doc.AutoFoliationState );
|
||||
}
|
||||
|
||||
public override XmlNode CloneNode(bool deep) {
|
||||
XmlDataDocument doc = (XmlDataDocument)(this.OwnerDocument);
|
||||
ElementState oldAutoFoliationState = doc.AutoFoliationState;
|
||||
doc.AutoFoliationState = ElementState.WeakFoliation;
|
||||
XmlElement element;
|
||||
try {
|
||||
Foliate( ElementState.WeakFoliation );
|
||||
element = (XmlElement)(base.CloneNode( deep ));
|
||||
// Clone should create a XmlBoundElement node
|
||||
Debug.Assert( element is XmlBoundElement );
|
||||
}
|
||||
finally {
|
||||
doc.AutoFoliationState = oldAutoFoliationState;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public override void WriteContentTo( XmlWriter w ) {
|
||||
DataPointer dp = new DataPointer( (XmlDataDocument)OwnerDocument, this );
|
||||
try {
|
||||
dp.AddPointer();
|
||||
WriteBoundElementContentTo( dp, w );
|
||||
}
|
||||
finally {
|
||||
dp.SetNoLongerUse();
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteTo( XmlWriter w ) {
|
||||
DataPointer dp = new DataPointer( (XmlDataDocument)OwnerDocument, this );
|
||||
try {
|
||||
dp.AddPointer();
|
||||
WriteRootBoundElementTo( dp, w );
|
||||
}
|
||||
finally {
|
||||
dp.SetNoLongerUse();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteRootBoundElementTo(DataPointer dp, XmlWriter w) {
|
||||
Debug.Assert( dp.NodeType == XmlNodeType.Element );
|
||||
XmlDataDocument doc = (XmlDataDocument)OwnerDocument;
|
||||
w.WriteStartElement( dp.Prefix, dp.LocalName, dp.NamespaceURI );
|
||||
int cAttr = dp.AttributeCount;
|
||||
bool bHasXSI = false;
|
||||
if ( cAttr > 0 ) {
|
||||
for ( int iAttr = 0; iAttr < cAttr; iAttr++ ) {
|
||||
dp.MoveToAttribute( iAttr );
|
||||
if ( dp.Prefix == "xmlns" && dp.LocalName == XmlDataDocument.XSI )
|
||||
bHasXSI = true;
|
||||
WriteTo( dp, w );
|
||||
dp.MoveToOwnerElement();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bHasXSI && doc.bLoadFromDataSet && doc.bHasXSINIL )
|
||||
w.WriteAttributeString( "xmlns", "xsi", "http://www.w3.org/2000/xmlns/", Keywords.XSINS );
|
||||
|
||||
|
||||
WriteBoundElementContentTo( dp, w );
|
||||
|
||||
// Force long end tag when the elem is not empty, even if there are no children.
|
||||
if ( dp.IsEmptyElement )
|
||||
w.WriteEndElement();
|
||||
else
|
||||
w.WriteFullEndElement();
|
||||
}
|
||||
|
||||
private static void WriteBoundElementTo( DataPointer dp, XmlWriter w ) {
|
||||
Debug.Assert( dp.NodeType == XmlNodeType.Element );
|
||||
w.WriteStartElement( dp.Prefix, dp.LocalName, dp.NamespaceURI );
|
||||
int cAttr = dp.AttributeCount;
|
||||
if ( cAttr > 0 ) {
|
||||
for ( int iAttr = 0; iAttr < cAttr; iAttr++ ) {
|
||||
dp.MoveToAttribute( iAttr );
|
||||
WriteTo( dp, w );
|
||||
dp.MoveToOwnerElement();
|
||||
}
|
||||
}
|
||||
|
||||
WriteBoundElementContentTo( dp, w );
|
||||
|
||||
// Force long end tag when the elem is not empty, even if there are no children.
|
||||
if ( dp.IsEmptyElement )
|
||||
w.WriteEndElement();
|
||||
else
|
||||
w.WriteFullEndElement();
|
||||
}
|
||||
|
||||
private static void WriteBoundElementContentTo( DataPointer dp, XmlWriter w ) {
|
||||
if ( !dp.IsEmptyElement && dp.MoveToFirstChild() ) {
|
||||
do {
|
||||
WriteTo( dp, w );
|
||||
}
|
||||
while ( dp.MoveToNextSibling() );
|
||||
|
||||
dp.MoveToParent();
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteTo( DataPointer dp, XmlWriter w ) {
|
||||
switch ( dp.NodeType ) {
|
||||
case XmlNodeType.Attribute:
|
||||
if ( !dp.IsDefault ) {
|
||||
w.WriteStartAttribute( dp.Prefix, dp.LocalName, dp.NamespaceURI );
|
||||
|
||||
if ( dp.MoveToFirstChild() ) {
|
||||
do {
|
||||
WriteTo( dp, w );
|
||||
}
|
||||
while ( dp.MoveToNextSibling() );
|
||||
|
||||
dp.MoveToParent();
|
||||
}
|
||||
|
||||
w.WriteEndAttribute();
|
||||
}
|
||||
break;
|
||||
|
||||
case XmlNodeType.Element:
|
||||
WriteBoundElementTo( dp, w );
|
||||
break;
|
||||
|
||||
case XmlNodeType.Text:
|
||||
w.WriteString(dp.Value);
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Assert( ((IXmlDataVirtualNode)dp).IsOnColumn( null ) );
|
||||
if ( dp.GetNode() != null )
|
||||
dp.GetNode().WriteTo( w );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override XmlNodeList GetElementsByTagName(string name) {
|
||||
// Retrieving nodes from the returned nodelist may cause foliation which causes new nodes to be created,
|
||||
// so the System.Xml iterator will throw if this happens during iteration. To avoid this, foliate everything
|
||||
// before iteration, so iteration will not cause foliation (and as a result of this, creation of new nodes).
|
||||
XmlNodeList tempNodeList = base.GetElementsByTagName(name);
|
||||
|
||||
int tempint = tempNodeList.Count;
|
||||
return tempNodeList;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user