| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- //------------------------------------------------------------------------------
- // <copyright file="DataPointer.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- // <owner current="true" primary="true">Microsoft</owner>
- // <owner current="true" primary="false">Microsoft</owner>
- //------------------------------------------------------------------------------
- #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;
- }
-
- }
- }
|