DataPointer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / NewXml / DataPointer.cs / 1305376 / DataPointer.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument 
namespace System.Xml {
    using System; 
    using System.Data;
    using System.Diagnostics;

    internal sealed class DataPointer : IXmlDataVirtualNode { 
        private XmlDataDocument doc;
        private XmlNode node; 
        private DataColumn column; 
        private bool fOnValue;
        private bool bNeedFoliate = false; 
        private bool _isInUse;

        internal DataPointer( XmlDataDocument doc, XmlNode node ) {
            this.doc = doc; 
            this.node = node;
            this.column = null; 
            this.fOnValue = false; 
            bNeedFoliate = false;
            this._isInUse = true; 
            AssertValid();
        }

        internal DataPointer( DataPointer pointer ) { 
            this.doc = pointer.doc;
            this.node = pointer.node; 
            this.column = pointer.column; 
            this.fOnValue = pointer.fOnValue;
            this.bNeedFoliate = false; 
            this._isInUse = true;
            AssertValid();
        }
 
        internal void AddPointer() {
            this.doc.AddPointer( (IXmlDataVirtualNode)this ); 
        } 

        // Returns the row element of the region that the pointer points into 
        private XmlBoundElement GetRowElement() {
            //AssertValid();

            XmlBoundElement rowElem; 
            if ( this.column != null ) {
                rowElem = this.node as XmlBoundElement; 
                Debug.Assert( rowElem != null ); 
                Debug.Assert( rowElem.Row != null );
                return rowElem; 
            }

            doc.Mapper.GetRegion( this.node, out rowElem );
            return rowElem; 
        }
 
        private DataRow Row { 
            get {
                //AssertValid(); 
                XmlBoundElement rowElem = GetRowElement();
                if ( rowElem == null )
                    return null;
 
                Debug.Assert( rowElem.Row != null );
                return rowElem.Row; 
            } 
        }
 
        private static bool IsFoliated( XmlNode node ) {
            if (node != null && node is XmlBoundElement)
                return((XmlBoundElement)node).IsFoliated;
            return true; 
        }
 
        internal void MoveTo( DataPointer pointer ) { 
            AssertValid();
            // You should not move outside of this document 
            Debug.Assert( node == this.doc || node.OwnerDocument == this.doc );

            this.doc = pointer.doc;
            this.node = pointer.node; 
            this.column = pointer.column;
            this.fOnValue = pointer.fOnValue; 
            AssertValid(); 
        }
        private void MoveTo( XmlNode node ) { 
            //AssertValid();
            // You should not move outside of this document
            Debug.Assert( node == this.doc || node.OwnerDocument == this.doc );
 
            this.node = node;
            this.column = null; 
            this.fOnValue = false; 
            AssertValid();
        } 

        private void MoveTo( XmlNode node, DataColumn column, bool fOnValue ) {
            //AssertValid();
            // You should not move outside of this document 
            Debug.Assert( node == this.doc || node.OwnerDocument == this.doc );
 
            this.node = node; 
            this.column = column;
            this.fOnValue = fOnValue; 
            AssertValid();
        }

        private DataColumn NextColumn( DataRow row, DataColumn col, bool fAttribute, bool fNulls ) { 
            if (row.RowState == DataRowState.Deleted)
                return null; 
 
            DataTable table = row.Table;
            DataColumnCollection columns = table.Columns; 
            int iColumn = (col != null) ? col.Ordinal + 1 : 0;
            int cColumns = columns.Count;
            DataRowVersion rowVersion = ( row.RowState == DataRowState.Detached ) ? DataRowVersion.Proposed : DataRowVersion.Current;
 
            for (; iColumn < cColumns; iColumn++) {
                DataColumn c = columns[iColumn]; 
                if (!doc.IsNotMapped( c ) && (c.ColumnMapping == MappingType.Attribute) == fAttribute && (fNulls || ! Convert.IsDBNull( row[c, rowVersion] ) ) ) 
                    return c;
            } 

            return null;
        }
 
        private DataColumn NthColumn( DataRow row, bool fAttribute, int iColumn, bool fNulls ) {
            DataColumn c = null; 
            while ((c = NextColumn( row, c, fAttribute, fNulls )) != null) { 
                if (iColumn == 0)
                    return c; 

                iColumn = checked((int)iColumn-1);
            }
            return null; 
        }
 
        private int ColumnCount( DataRow row, bool fAttribute, bool fNulls ) { 
            DataColumn c = null;
            int count = 0; 
            while ((c = NextColumn( row, c, fAttribute, fNulls )) != null) {
                count++;
            }
            return count; 
        }
 
        internal bool MoveToFirstChild() { 
            RealFoliate();
            AssertValid(); 
            if (node == null)
                return false;

            if (column != null) { 
                if (fOnValue)
                    return false; 
 
                fOnValue = true;
                return true; 
            }
            else if (!IsFoliated( node )) {
                // find virtual column elements first
                DataColumn c = NextColumn( Row, null, false, false ); 
                if (c != null) {
                    MoveTo( node, c, doc.IsTextOnly(c) ); 
                    return true; 
                }
            } 

            // look for anything
            XmlNode n = doc.SafeFirstChild( node );
            if (n != null) { 
                MoveTo(n);
                return true; 
            } 

            return false; 
        }

        internal bool MoveToNextSibling() {
            RealFoliate(); 
            AssertValid();
            if (node != null) { 
                if (column != null) { 
                    if (fOnValue && !doc.IsTextOnly(column))
                        return false; 

                    DataColumn c = NextColumn( Row, column, false, false );
                    if (c != null) {
                        MoveTo( this.node, c, false ); 
                        return true;
                    } 
 
                    XmlNode n = doc.SafeFirstChild( node );
                    if (n != null) { 
                        MoveTo( n );
                        return true;
                    }
                } 
                else {
                    XmlNode n = doc.SafeNextSibling( node ); 
                    if (n != null) { 
                        MoveTo(n);
                        return true; 
                    }
                }
            }
 
            return false;
        } 
 
        internal bool MoveToParent() {
            RealFoliate(); 
            AssertValid();
            if (node != null) {
                if (column != null) {
                    if (fOnValue && !doc.IsTextOnly(column)) { 
                        MoveTo( node, column, false );
                        return true; 
                    } 

                    if (column.ColumnMapping != MappingType.Attribute) { 
                        MoveTo( node, null, false );
                        return true;
                    }
                } 
                else {
                    XmlNode n = node.ParentNode; 
                    if (n != null) { 
                        MoveTo(n);
                        return true; 
                    }
                }
            }
            return false; 
        }
 
        internal bool MoveToOwnerElement() { 
            RealFoliate();
            AssertValid(); 
            if (node != null) {
                if (column != null) {
                    if (fOnValue || doc.IsTextOnly(column) || column.ColumnMapping != MappingType.Attribute)
                        return false; 

                    MoveTo( node, null, false ); 
                    return true; 
                }
                else if (node.NodeType == XmlNodeType.Attribute) { 
                    XmlNode n = ((XmlAttribute)node).OwnerElement;
                    if (n != null) {
                        MoveTo( n, null, false );
                        return true; 
                    }
                } 
            } 

            return false; 
        }


        internal int AttributeCount { 
            get {
                RealFoliate(); 
                AssertValid(); 
                if (node != null) {
                    if (column == null && node.NodeType == XmlNodeType.Element) { 
                        if (!IsFoliated( node )) {
                            return ColumnCount( Row, true, false );
                        }
                        else 
                            return node.Attributes.Count;
                    } 
                } 
                return 0;
            } 
        }

        internal bool MoveToAttribute( int i ) {
            RealFoliate(); 
            AssertValid();
            if ( i < 0 ) 
                return false; 
            if (node != null) {
                if ((column == null || column.ColumnMapping == MappingType.Attribute) && node.NodeType == XmlNodeType.Element) { 
                    if (!IsFoliated( node )) {
                        DataColumn c = NthColumn( Row, true, i, false );
                        if (c != null) {
                            MoveTo( node, c, false ); 
                            return true;
                        } 
                    } 
                    else {
                        XmlNode n = node.Attributes.Item(i); 
                        if (n != null) {
                            MoveTo( n, null, false );
                            return true;
                        } 
                    }
                } 
            } 
            return false;
        } 

        internal XmlNodeType NodeType {
            get {
                RealFoliate(); 
                AssertValid();
                if (this.node == null) { 
                    return XmlNodeType.None; 
                }
                else if (this.column == null) { 
                    return this.node.NodeType;
                }
                else if (this.fOnValue) {
                    return XmlNodeType.Text; 
                }
                else if (this.column.ColumnMapping == MappingType.Attribute) { 
                    return XmlNodeType.Attribute; 
                }
                else { 
                    return XmlNodeType.Element;
                }
            }
        } 

        internal string LocalName { 
            get { 
                RealFoliate();
                AssertValid(); 
                if (this.node == null) {
                    return string.Empty;
                }else if (this.column == null) {
                    String name = node.LocalName; 
                    Debug.Assert( name != null );
                    if ( IsLocalNameEmpty( this.node.NodeType ) ) 
                        return String.Empty; 
                    return name;
                } 
                else if (this.fOnValue) {
                    return String.Empty;
                }
                else { 
                    return doc.NameTable.Add(column.EncodedColumnName);
                } 
            } 
        }
 
        internal string NamespaceURI {
            get {
                RealFoliate();
                AssertValid(); 
                if (this.node == null) {
                    return string.Empty; 
                } 
                else if (this.column == null) {
                    return node.NamespaceURI; 
                }
                else if (this.fOnValue) {
                    return string.Empty;
                } 
                else {
                    return doc.NameTable.Add(column.Namespace); 
                } 
            }
        } 

        internal string Name {
            get {
                RealFoliate(); 
                AssertValid();
                if (this.node == null) { 
                    return string.Empty; 
                }
                else if (this.column == null) { 
                    String name = node.Name;
                    //Again it could be String.Empty at null position
                    Debug.Assert( name != null );
                    if ( IsLocalNameEmpty( this.node.NodeType ) ) 
                        return String.Empty;
                    return name; 
                } 
                else {
                    string prefix = Prefix; 
                    string lname = LocalName;
                    if (prefix != null && prefix.Length > 0) {
                        if (lname != null && lname.Length > 0) {
                            return doc.NameTable.Add( prefix + ":" + lname ); 
                        }
                        else { 
                            return prefix; 
                        }
                    } 
                    else {
                        return lname;
                    }
                } 
            }
        } 
 

        private bool IsLocalNameEmpty ( XmlNodeType nt) { 
                switch ( nt ) {
                    case XmlNodeType.None :
                    case XmlNodeType.Text :
                    case XmlNodeType.CDATA : 
                    case XmlNodeType.Comment :
                    case XmlNodeType.Document : 
                    case XmlNodeType.DocumentFragment : 
                    case XmlNodeType.Whitespace :
                    case XmlNodeType.SignificantWhitespace : 
                    case XmlNodeType.EndElement :
                    case XmlNodeType.EndEntity :
                        return true;
                    case XmlNodeType.Element : 
                    case XmlNodeType.Attribute :
                    case XmlNodeType.EntityReference : 
                    case XmlNodeType.Entity : 
                    case XmlNodeType.ProcessingInstruction :
                    case XmlNodeType.DocumentType : 
                    case XmlNodeType.Notation :
                    case XmlNodeType.XmlDeclaration :
                        return false;
                    default : 
                        return true;
                } 
            } 

        internal string Prefix { 
            get {
                RealFoliate();
                AssertValid();
                if (this.node == null) { 
                    return string.Empty;
                } 
                else if (this.column == null) { 
                    return node.Prefix;
                } 
                else {
                    return string.Empty;
                }
            } 
        }
 
        internal string Value { 
            get {
                RealFoliate(); 
                AssertValid();
                if (this.node == null) {
                    return null;
                } 
                else if (this.column == null) {
                    return this.node.Value; 
                } 
                else if (this.column.ColumnMapping == MappingType.Attribute || this.fOnValue) {
                    DataRow row = this.Row; 
                    DataRowVersion rowVersion = ( row.RowState == DataRowState.Detached ) ? DataRowVersion.Proposed : DataRowVersion.Current;
                    object value = row[ this.column, rowVersion ];
                    if ( ! Convert.IsDBNull( value ) )
                        return this.column.ConvertObjectToXml( value ); 
                    return null;
                } 
                else { 
                    // column element has no value
                    return null; 
                }
            }
        }
 
        bool IXmlDataVirtualNode.IsOnNode( XmlNode nodeToCheck ) {
            RealFoliate(); 
            return nodeToCheck == this.node; 
        }
 
        bool IXmlDataVirtualNode.IsOnColumn( DataColumn col ) {
            RealFoliate();
            return col == this.column;
        } 

        internal XmlNode GetNode() { 
            return this.node; 
        }
 
        internal bool IsEmptyElement {
            get {
                RealFoliate();
                AssertValid(); 
                if (node != null && column == null) {
                    // 
                    if (node.NodeType == XmlNodeType.Element) { 
                        return((XmlElement)node).IsEmpty;
                    } 
                }
                return false;
            }
        } 

        internal bool IsDefault { 
            get { 
                RealFoliate();
                AssertValid(); 
                if (node != null && column == null && node.NodeType == XmlNodeType.Attribute) {
                    return !((XmlAttribute)node).Specified;
                }
 
                return false;
            } 
        } 

        void IXmlDataVirtualNode.OnFoliated( XmlNode foliatedNode ) { 
            // update the pointer if the element node has been foliated
            if (node == foliatedNode) {
                // if already on this node, nothing to do!
                if (column == null) 
                    return;
                bNeedFoliate = true; 
            } 
        }
 
        internal void RealFoliate() {
            if ( !bNeedFoliate )
                return;
 
            XmlNode n = null;
 
            if (doc.IsTextOnly( column )) { 
                n = node.FirstChild;
            } 
            else {
                if (column.ColumnMapping == MappingType.Attribute) {
                    n = node.Attributes.GetNamedItem( column.EncodedColumnName, column.Namespace );
                } 
                else {
                    for (n = node.FirstChild; n != null; n = n.NextSibling) { 
                        if (n.LocalName == column.EncodedColumnName && n.NamespaceURI == column.Namespace) 
                            break;
                    } 
                }

                if (n != null && fOnValue)
                    n = n.FirstChild; 
            }
 
            if (n == null) 
                throw new InvalidOperationException(Res.GetString(Res.DataDom_Foliation));
 
            // Cannot use MoveTo( n ); b/c the initial state for MoveTo is invalid (region is foliated but this is not)
            this.node = n;
            this.column = null;
            this.fOnValue = false; 
            AssertValid();
 
            bNeedFoliate = false; 
        }
 
        //for the 6 properties below, only when the this.column == null that the nodetype could be XmlDeclaration node
        internal String PublicId {
            get {
                XmlNodeType nt = NodeType; 
                switch ( nt ) {
                    case XmlNodeType.DocumentType : { 
                        Debug.Assert( this.column == null ); 
                        return ( ( XmlDocumentType ) (this.node)).PublicId;
                    } 
                    case XmlNodeType.Entity : {
                        Debug.Assert( this.column == null );
                        return ( ( XmlEntity ) (this.node)).PublicId;
                    } 
                    case XmlNodeType.Notation : {
                        Debug.Assert( this.column == null ); 
                        return ( ( XmlNotation ) (this.node)).PublicId; 
                    }
                } 
                return null;
            }
        }
 
        internal String SystemId {
            get { 
                XmlNodeType nt = NodeType; 
                switch ( nt ) {
                    case XmlNodeType.DocumentType : { 
                        Debug.Assert( this.column == null );
                        return ( ( XmlDocumentType ) (this.node)).SystemId;
                    }
                    case XmlNodeType.Entity : { 
                        Debug.Assert( this.column == null );
                        return ( ( XmlEntity ) (this.node)).SystemId; 
                    } 
                    case XmlNodeType.Notation : {
                        Debug.Assert( this.column == null ); 
                        return ( ( XmlNotation ) (this.node)).SystemId;
                    }
                }
                return null; 
            }
        } 
 
        internal String InternalSubset {
            get { 
                if ( NodeType == XmlNodeType.DocumentType ) {
                    Debug.Assert( this.column == null );
                    return ( ( XmlDocumentType ) (this.node)).InternalSubset;
                } 
                return null;
            } 
        } 

        internal XmlDeclaration Declaration { 
            get {
                XmlNode child = doc.SafeFirstChild(doc);
                if ( child != null && child.NodeType == XmlNodeType.XmlDeclaration )
                    return (XmlDeclaration)child; 
                return null;
            } 
        } 

        internal String Encoding { 
            get {
                if ( NodeType == XmlNodeType.XmlDeclaration ) {
                    Debug.Assert( this.column == null );
                    return ( ( XmlDeclaration ) (this.node)).Encoding; 
                } else if ( NodeType == XmlNodeType.Document ) {
                    XmlDeclaration dec = Declaration; 
                    if ( dec != null ) 
                        return dec.Encoding;
                } 
                return null;
            }
        }
 
        internal String Standalone {
            get { 
                if ( NodeType == XmlNodeType.XmlDeclaration ) { 
                    Debug.Assert( this.column == null );
                    return ( ( XmlDeclaration ) (this.node)).Standalone; 
                } else if ( NodeType == XmlNodeType.Document ) {
                    XmlDeclaration dec = Declaration;
                    if ( dec != null )
                        return dec.Standalone; 
                }
                return null; 
            } 
        }
 
        internal String Version {
            get {
                if ( NodeType == XmlNodeType.XmlDeclaration ) {
                    Debug.Assert( this.column == null ); 
                    return ( ( XmlDeclaration ) (this.node)).Version;
                } else if ( NodeType == XmlNodeType.Document ) { 
                    XmlDeclaration dec = Declaration; 
                    if ( dec != null )
                        return dec.Version; 
                }
                return null;
            }
        } 

        [System.Diagnostics.Conditional("DEBUG")] 
        private void AssertValid() { 
            // This pointer must be int the document list
            if ( this.column != null ) { 
                // We must be on a de-foliated region
                XmlBoundElement rowElem = this.node as XmlBoundElement;
                Debug.Assert( rowElem != null );
 
                DataRow row = rowElem.Row;
                Debug.Assert( row != null ); 
 
                ElementState state = rowElem.ElementState;
                Debug.Assert( state == ElementState.Defoliated, "Region is accessed using column, but it's state is FOLIATED" ); 

                // We cannot be on a column for which the value is DBNull
                DataRowVersion rowVersion = ( row.RowState == DataRowState.Detached ) ? DataRowVersion.Proposed : DataRowVersion.Current;
                Debug.Assert( ! Convert.IsDBNull( row[ this.column, rowVersion ] ) ); 

                // If we are on the Text column, we should always have fOnValue == true 
                Debug.Assert( (this.column.ColumnMapping == MappingType.SimpleContent) ? (this.fOnValue == true) : true ); 
            }
        } 

        bool IXmlDataVirtualNode.IsInUse() {
            return _isInUse;
        } 

        internal void SetNoLongerUse() { 
            this.node = null; 
            this.column = null;
            this.fOnValue = false; 
            this.bNeedFoliate = false;
            this._isInUse = false;
        }
 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK