2016-08-03 10:59:49 +00:00
//------------------------------------------------------------------------------
// <copyright file="XmlNodeReader.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
2017-08-21 15:34:15 +00:00
// <owner current="true" primary="true">Microsoft</owner>
2016-08-03 10:59:49 +00:00
//------------------------------------------------------------------------------
namespace System.Xml
{
using System ;
using System.Text ;
using System.IO ;
using System.Diagnostics ;
using System.Collections ;
using System.Collections.Generic ;
using System.Xml.Schema ;
using System.Globalization ;
internal class XmlNodeReaderNavigator {
XmlNode curNode ;
XmlNode elemNode ;
XmlNode logNode ;
int attrIndex ;
int logAttrIndex ;
//presave these 2 variables since they shouldn't change.
XmlNameTable nameTable ;
XmlDocument doc ;
int nAttrInd ; //used to identify virtual attributes of DocumentType node and XmlDeclaration node
const String strPublicID = "PUBLIC" ;
const String strSystemID = "SYSTEM" ;
const String strVersion = "version" ;
const String strStandalone = "standalone" ;
const String strEncoding = "encoding" ;
//caching variables for perf reasons
int nDeclarationAttrCount ;
int nDocTypeAttrCount ;
//variables for roll back the moves
int nLogLevel ;
int nLogAttrInd ;
bool bLogOnAttrVal ;
bool bCreatedOnAttribute ;
internal struct VirtualAttribute {
internal String name ;
internal String value ;
internal VirtualAttribute ( String name , String value ) {
this . name = name ;
this . value = value ;
}
} ;
internal VirtualAttribute [ ] decNodeAttributes = {
new VirtualAttribute ( null , null ) ,
new VirtualAttribute ( null , null ) ,
new VirtualAttribute ( null , null )
} ;
internal VirtualAttribute [ ] docTypeNodeAttributes = {
new VirtualAttribute ( null , null ) ,
new VirtualAttribute ( null , null )
} ;
bool bOnAttrVal ;
public XmlNodeReaderNavigator ( XmlNode node ) {
curNode = node ;
logNode = node ;
XmlNodeType nt = curNode . NodeType ;
if ( nt = = XmlNodeType . Attribute ) {
elemNode = null ;
attrIndex = - 1 ;
bCreatedOnAttribute = true ;
}
else {
elemNode = node ;
attrIndex = - 1 ;
bCreatedOnAttribute = false ;
}
//presave this for pref reason since it shouldn't change.
if ( nt = = XmlNodeType . Document )
this . doc = ( XmlDocument ) curNode ;
else
this . doc = node . OwnerDocument ;
this . nameTable = doc . NameTable ;
this . nAttrInd = - 1 ;
//initialize the caching variables
this . nDeclarationAttrCount = - 1 ;
this . nDocTypeAttrCount = - 1 ;
this . bOnAttrVal = false ;
this . bLogOnAttrVal = false ;
}
public XmlNodeType NodeType {
get {
XmlNodeType nt = curNode . NodeType ;
if ( nAttrInd ! = - 1 ) {
Debug . Assert ( nt = = XmlNodeType . XmlDeclaration | | nt = = XmlNodeType . DocumentType ) ;
if ( this . bOnAttrVal )
return XmlNodeType . Text ;
else
return XmlNodeType . Attribute ;
}
return nt ;
}
}
public String NamespaceURI {
get { return curNode . NamespaceURI ; }
}
public String Name {
get {
if ( nAttrInd ! = - 1 ) {
Debug . Assert ( curNode . NodeType = = XmlNodeType . XmlDeclaration | | curNode . NodeType = = XmlNodeType . DocumentType ) ;
if ( this . bOnAttrVal )
return String . Empty ; //Text node's name is String.Empty
else {
Debug . Assert ( nAttrInd > = 0 & & nAttrInd < AttributeCount ) ;
if ( curNode . NodeType = = XmlNodeType . XmlDeclaration )
return decNodeAttributes [ nAttrInd ] . name ;
else
return docTypeNodeAttributes [ nAttrInd ] . name ;
}
}
if ( IsLocalNameEmpty ( curNode . NodeType ) )
return String . Empty ;
return curNode . Name ;
}
}
public String LocalName {
get {
if ( nAttrInd ! = - 1 )
//for the nodes in this case, their LocalName should be the same as their name
return Name ;
if ( IsLocalNameEmpty ( curNode . NodeType ) )
return String . Empty ;
return curNode . LocalName ;
}
}
internal bool IsOnAttrVal {
get {
return this . bOnAttrVal ;
}
}
internal XmlNode OwnerElementNode {
get {
if ( this . bCreatedOnAttribute )
return null ;
return this . elemNode ;
}
}
internal bool CreatedOnAttribute {
get {
return this . bCreatedOnAttribute ;
}
}
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 ;
}
}
public String Prefix {
get { return curNode . Prefix ; }
}
public bool HasValue {
//In DOM, DocumentType node and XmlDeclaration node doesn't value
//In XPathNavigator, XmlDeclaration node's value is its InnerText; DocumentType doesn't have value
//In XmlReader, DocumentType node's value is its InternalSubset which is never null ( at least String.Empty )
get {
if ( nAttrInd ! = - 1 ) {
//Pointing at the one of virtual attributes of Declaration or DocumentType nodes
Debug . Assert ( curNode . NodeType = = XmlNodeType . XmlDeclaration | | curNode . NodeType = = XmlNodeType . DocumentType ) ;
Debug . Assert ( nAttrInd > = 0 & & nAttrInd < AttributeCount ) ;
return true ;
}
if ( curNode . Value ! = null | | curNode . NodeType = = XmlNodeType . DocumentType )
return true ;
return false ;
}
}
public String Value {
//See comments in HasValue
get {
String retValue = null ;
XmlNodeType nt = curNode . NodeType ;
if ( nAttrInd ! = - 1 ) {
//Pointing at the one of virtual attributes of Declaration or DocumentType nodes
Debug . Assert ( nt = = XmlNodeType . XmlDeclaration | | nt = = XmlNodeType . DocumentType ) ;
Debug . Assert ( nAttrInd > = 0 & & nAttrInd < AttributeCount ) ;
if ( curNode . NodeType = = XmlNodeType . XmlDeclaration )
return decNodeAttributes [ nAttrInd ] . value ;
else
return docTypeNodeAttributes [ nAttrInd ] . value ;
}
if ( nt = = XmlNodeType . DocumentType )
retValue = ( ( XmlDocumentType ) curNode ) . InternalSubset ; //in this case nav.Value will be null
else if ( nt = = XmlNodeType . XmlDeclaration ) {
StringBuilder strb = new StringBuilder ( String . Empty ) ;
if ( nDeclarationAttrCount = = - 1 )
InitDecAttr ( ) ;
for ( int i = 0 ; i < nDeclarationAttrCount ; i + + ) {
strb . Append ( decNodeAttributes [ i ] . name + "=\"" + decNodeAttributes [ i ] . value + "\"" ) ;
if ( i ! = ( nDeclarationAttrCount - 1 ) )
strb . Append ( " " ) ;
}
retValue = strb . ToString ( ) ;
} else
retValue = curNode . Value ;
return ( retValue = = null ) ? String . Empty : retValue ;
}
}
public String BaseURI {
get { return curNode . BaseURI ; }
}
public XmlSpace XmlSpace {
get { return curNode . XmlSpace ; }
}
public String XmlLang {
get { return curNode . XmlLang ; }
}
public bool IsEmptyElement {
get {
if ( curNode . NodeType = = XmlNodeType . Element ) {
return ( ( XmlElement ) curNode ) . IsEmpty ;
}
return false ;
}
}
public bool IsDefault {
get {
if ( curNode . NodeType = = XmlNodeType . Attribute ) {
return ! ( ( XmlAttribute ) curNode ) . Specified ;
}
return false ;
}
}
public IXmlSchemaInfo SchemaInfo {
get {
return curNode . SchemaInfo ;
}
}
public XmlNameTable NameTable {
get { return nameTable ; }
}
public int AttributeCount {
get {
if ( this . bCreatedOnAttribute )
return 0 ;
XmlNodeType nt = curNode . NodeType ;
if ( nt = = XmlNodeType . Element )
return ( ( XmlElement ) curNode ) . Attributes . Count ;
else if ( nt = = XmlNodeType . Attribute
| | ( this . bOnAttrVal & & nt ! = XmlNodeType . XmlDeclaration & & nt ! = XmlNodeType . DocumentType ) )
return elemNode . Attributes . Count ;
else if ( nt = = XmlNodeType . XmlDeclaration ) {
if ( nDeclarationAttrCount ! = - 1 )
return nDeclarationAttrCount ;
InitDecAttr ( ) ;
return nDeclarationAttrCount ;
} else if ( nt = = XmlNodeType . DocumentType ) {
if ( nDocTypeAttrCount ! = - 1 )
return nDocTypeAttrCount ;
InitDocTypeAttr ( ) ;
return nDocTypeAttrCount ;
}
return 0 ;
}
}
private void CheckIndexCondition ( int attributeIndex ) {
if ( attributeIndex < 0 | | attributeIndex > = AttributeCount ) {
throw new ArgumentOutOfRangeException ( "attributeIndex" ) ;
}
}
//8 functions below are the helper functions to deal with virtual attributes of XmlDeclaration nodes and DocumentType nodes.
private void InitDecAttr ( ) {
int i = 0 ;
String strTemp = doc . Version ;
if ( strTemp ! = null & & strTemp . Length ! = 0 ) {
decNodeAttributes [ i ] . name = strVersion ;
decNodeAttributes [ i ] . value = strTemp ;
i + + ;
}
strTemp = doc . Encoding ;
if ( strTemp ! = null & & strTemp . Length ! = 0 ) {
decNodeAttributes [ i ] . name = strEncoding ;
decNodeAttributes [ i ] . value = strTemp ;
i + + ;
}
strTemp = doc . Standalone ;
if ( strTemp ! = null & & strTemp . Length ! = 0 ) {
decNodeAttributes [ i ] . name = strStandalone ;
decNodeAttributes [ i ] . value = strTemp ;
i + + ;
}
nDeclarationAttrCount = i ;
}
public String GetDeclarationAttr ( XmlDeclaration decl , String name ) {
//PreCondition: curNode is pointing at Declaration node or one of its virtual attributes
if ( name = = strVersion )
return decl . Version ;
if ( name = = strEncoding )
return decl . Encoding ;
if ( name = = strStandalone )
return decl . Standalone ;
return null ;
}
public String GetDeclarationAttr ( int i ) {
if ( nDeclarationAttrCount = = - 1 )
InitDecAttr ( ) ;
return decNodeAttributes [ i ] . value ;
}
public int GetDecAttrInd ( String name ) {
if ( nDeclarationAttrCount = = - 1 )
InitDecAttr ( ) ;
for ( int i = 0 ; i < nDeclarationAttrCount ; i + + ) {
if ( decNodeAttributes [ i ] . name = = name )
return i ;
}
return - 1 ;
}
private void InitDocTypeAttr ( ) {
int i = 0 ;
XmlDocumentType docType = doc . DocumentType ;
if ( docType = = null ) {
nDocTypeAttrCount = 0 ;
return ;
}
String strTemp = docType . PublicId ;
if ( strTemp ! = null ) {
docTypeNodeAttributes [ i ] . name = strPublicID ;
docTypeNodeAttributes [ i ] . value = strTemp ;
i + + ;
}
strTemp = docType . SystemId ;
if ( strTemp ! = null ) {
docTypeNodeAttributes [ i ] . name = strSystemID ;
docTypeNodeAttributes [ i ] . value = strTemp ;
i + + ;
}
nDocTypeAttrCount = i ;
}
public String GetDocumentTypeAttr ( XmlDocumentType docType , String name ) {
//PreCondition: nav is pointing at DocumentType node or one of its virtual attributes
if ( name = = strPublicID )
return docType . PublicId ;
if ( name = = strSystemID )
return docType . SystemId ;
return null ;
}
public String GetDocumentTypeAttr ( int i ) {
if ( nDocTypeAttrCount = = - 1 )
InitDocTypeAttr ( ) ;
return docTypeNodeAttributes [ i ] . value ;
}
public int GetDocTypeAttrInd ( String name ) {
if ( nDocTypeAttrCount = = - 1 )
InitDocTypeAttr ( ) ;
for ( int i = 0 ; i < nDocTypeAttrCount ; i + + ) {
if ( docTypeNodeAttributes [ i ] . name = = name )
return i ;
}
return - 1 ;
}
private String GetAttributeFromElement ( XmlElement elem , String name ) {
XmlAttribute attr = elem . GetAttributeNode ( name ) ;
if ( attr ! = null )
return attr . Value ;
return null ;
}
public String GetAttribute ( String name ) {
if ( this . bCreatedOnAttribute )
return null ;
switch ( curNode . NodeType ) {
case XmlNodeType . Element :
return GetAttributeFromElement ( ( XmlElement ) curNode , name ) ;
case XmlNodeType . Attribute :
return GetAttributeFromElement ( ( XmlElement ) elemNode , name ) ;
case XmlNodeType . XmlDeclaration :
return GetDeclarationAttr ( ( XmlDeclaration ) curNode , name ) ;
case XmlNodeType . DocumentType :
return GetDocumentTypeAttr ( ( XmlDocumentType ) curNode , name ) ;
}
return null ;
}
private String GetAttributeFromElement ( XmlElement elem , String name , String ns ) {
XmlAttribute attr = elem . GetAttributeNode ( name , ns ) ;
if ( attr ! = null )
return attr . Value ;
return null ;
}
public String GetAttribute ( String name , String ns ) {
if ( this . bCreatedOnAttribute )
return null ;
switch ( curNode . NodeType ) {
case XmlNodeType . Element :
return GetAttributeFromElement ( ( XmlElement ) curNode , name , ns ) ;
case XmlNodeType . Attribute :
return GetAttributeFromElement ( ( XmlElement ) elemNode , name , ns ) ;
case XmlNodeType . XmlDeclaration :
return ( ns . Length = = 0 ) ? GetDeclarationAttr ( ( XmlDeclaration ) curNode , name ) : null ;
case XmlNodeType . DocumentType :
return ( ns . Length = = 0 ) ? GetDocumentTypeAttr ( ( XmlDocumentType ) curNode , name ) : null ;
}
return null ;
}
public String GetAttribute ( int attributeIndex ) {
if ( this . bCreatedOnAttribute )
return null ;
switch ( curNode . NodeType ) {
case XmlNodeType . Element :
CheckIndexCondition ( attributeIndex ) ;
return ( ( XmlElement ) curNode ) . Attributes [ attributeIndex ] . Value ;
case XmlNodeType . Attribute :
CheckIndexCondition ( attributeIndex ) ;
return ( ( XmlElement ) elemNode ) . Attributes [ attributeIndex ] . Value ;
case XmlNodeType . XmlDeclaration : {
CheckIndexCondition ( attributeIndex ) ;
return GetDeclarationAttr ( attributeIndex ) ;
}
case XmlNodeType . DocumentType : {
CheckIndexCondition ( attributeIndex ) ;
return GetDocumentTypeAttr ( attributeIndex ) ;
}
}
throw new ArgumentOutOfRangeException ( "attributeIndex" ) ; //for other senario, AttributeCount is 0, i has to be out of range
}
public void LogMove ( int level ) {
logNode = curNode ;
nLogLevel = level ;
nLogAttrInd = nAttrInd ;
logAttrIndex = attrIndex ;
this . bLogOnAttrVal = this . bOnAttrVal ;
}
//The function has to be used in pair with ResetMove when the operation fails after LogMove() is
// called because it relies on the values of nOrigLevel, logNav and nOrigAttrInd to be acurate.
public void RollBackMove ( ref int level ) {
curNode = logNode ;
level = nLogLevel ;
nAttrInd = nLogAttrInd ;
attrIndex = logAttrIndex ;
this . bOnAttrVal = this . bLogOnAttrVal ;
}
private bool IsOnDeclOrDocType {
get {
XmlNodeType nt = curNode . NodeType ;
return ( nt = = XmlNodeType . XmlDeclaration | | nt = = XmlNodeType . DocumentType ) ;
}
}
public void ResetToAttribute ( ref int level ) {
//the current cursor is pointing at one of the attribute children -- this could be caused by
// the calls to ReadAttributeValue(..)
if ( this . bCreatedOnAttribute )
return ;
if ( this . bOnAttrVal ) {
if ( IsOnDeclOrDocType ) {
level - = 2 ;
} else {
while ( curNode . NodeType ! = XmlNodeType . Attribute & & ( ( curNode = curNode . ParentNode ) ! = null ) )
level - - ;
}
this . bOnAttrVal = false ;
}
}
public void ResetMove ( ref int level , ref XmlNodeType nt ) {
LogMove ( level ) ;
if ( this . bCreatedOnAttribute )
return ;
if ( nAttrInd ! = - 1 ) {
Debug . Assert ( IsOnDeclOrDocType ) ;
if ( this . bOnAttrVal ) {
level - - ;
this . bOnAttrVal = false ;
}
nLogAttrInd = nAttrInd ;
level - - ;
nAttrInd = - 1 ;
nt = curNode . NodeType ;
return ;
}
if ( this . bOnAttrVal & & curNode . NodeType ! = XmlNodeType . Attribute )
ResetToAttribute ( ref level ) ;
if ( curNode . NodeType = = XmlNodeType . Attribute ) {
curNode = ( ( XmlAttribute ) curNode ) . OwnerElement ;
attrIndex = - 1 ;
level - - ;
nt = XmlNodeType . Element ;
}
if ( curNode . NodeType = = XmlNodeType . Element )
elemNode = curNode ;
}
public bool MoveToAttribute ( string name ) {
return MoveToAttribute ( name , string . Empty ) ;
}
private bool MoveToAttributeFromElement ( XmlElement elem , String name , String ns ) {
XmlAttribute attr = null ;
if ( ns . Length = = 0 )
attr = elem . GetAttributeNode ( name ) ;
else
attr = elem . GetAttributeNode ( name , ns ) ;
if ( attr ! = null ) {
this . bOnAttrVal = false ;
elemNode = elem ;
curNode = attr ;
attrIndex = elem . Attributes . FindNodeOffsetNS ( attr ) ;
if ( attrIndex ! = - 1 ) {
return true ;
}
}
return false ;
}
public bool MoveToAttribute ( string name , string namespaceURI ) {
if ( this . bCreatedOnAttribute )
return false ;
XmlNodeType nt = curNode . NodeType ;
if ( nt = = XmlNodeType . Element )
return MoveToAttributeFromElement ( ( XmlElement ) curNode , name , namespaceURI ) ;
else if ( nt = = XmlNodeType . Attribute )
return MoveToAttributeFromElement ( ( XmlElement ) elemNode , name , namespaceURI ) ;
else if ( nt = = XmlNodeType . XmlDeclaration & & namespaceURI . Length = = 0 ) {
if ( ( nAttrInd = GetDecAttrInd ( name ) ) ! = - 1 ) {
this . bOnAttrVal = false ;
return true ;
}
} else if ( nt = = XmlNodeType . DocumentType & & namespaceURI . Length = = 0 ) {
if ( ( nAttrInd = GetDocTypeAttrInd ( name ) ) ! = - 1 ) {
this . bOnAttrVal = false ;
return true ;
}
}
return false ;
}
public void MoveToAttribute ( int attributeIndex ) {
if ( this . bCreatedOnAttribute )
return ;
XmlAttribute attr = null ;
switch ( curNode . NodeType ) {
case XmlNodeType . Element :
CheckIndexCondition ( attributeIndex ) ;
attr = ( ( XmlElement ) curNode ) . Attributes [ attributeIndex ] ;
if ( attr ! = null ) {
elemNode = curNode ;
curNode = ( XmlNode ) attr ;
attrIndex = attributeIndex ;
}
break ;
case XmlNodeType . Attribute :
CheckIndexCondition ( attributeIndex ) ;
attr = ( ( XmlElement ) elemNode ) . Attributes [ attributeIndex ] ;
if ( attr ! = null ) {
curNode = ( XmlNode ) attr ;
attrIndex = attributeIndex ;
}
break ;
case XmlNodeType . XmlDeclaration :
case XmlNodeType . DocumentType :
CheckIndexCondition ( attributeIndex ) ;
nAttrInd = attributeIndex ;
break ;
}
}
public bool MoveToNextAttribute ( ref int level ) {
if ( this . bCreatedOnAttribute )
return false ;
XmlNodeType nt = curNode . NodeType ;
if ( nt = = XmlNodeType . Attribute ) {
if ( attrIndex > = ( elemNode . Attributes . Count - 1 ) )
return false ;
else {
curNode = elemNode . Attributes [ + + attrIndex ] ;
return true ;
}
} else if ( nt = = XmlNodeType . Element ) {
if ( curNode . Attributes . Count > 0 ) {
level + + ;
elemNode = curNode ;
curNode = curNode . Attributes [ 0 ] ;
attrIndex = 0 ;
return true ;
}
} else if ( nt = = XmlNodeType . XmlDeclaration ) {
if ( nDeclarationAttrCount = = - 1 )
InitDecAttr ( ) ;
nAttrInd + + ;
if ( nAttrInd < nDeclarationAttrCount ) {
if ( nAttrInd = = 0 ) level + + ;
this . bOnAttrVal = false ;
return true ;
}
nAttrInd - - ;
} else if ( nt = = XmlNodeType . DocumentType ) {
if ( nDocTypeAttrCount = = - 1 )
InitDocTypeAttr ( ) ;
nAttrInd + + ;
if ( nAttrInd < nDocTypeAttrCount ) {
if ( nAttrInd = = 0 ) level + + ;
this . bOnAttrVal = false ;
return true ;
}
nAttrInd - - ;
}
return false ;
}
public bool MoveToParent ( ) {
XmlNode parent = curNode . ParentNode ;
if ( parent ! = null ) {
curNode = parent ;
if ( ! bOnAttrVal )
attrIndex = 0 ;
return true ;
}
return false ;
}
public bool MoveToFirstChild ( ) {
XmlNode firstChild = curNode . FirstChild ;
if ( firstChild ! = null ) {
curNode = firstChild ;
if ( ! bOnAttrVal )
attrIndex = - 1 ;
return true ;
}
return false ;
}
private bool MoveToNextSibling ( XmlNode node ) {
XmlNode nextSibling = node . NextSibling ;
if ( nextSibling ! = null ) {
curNode = nextSibling ;
if ( ! bOnAttrVal )
attrIndex = - 1 ;
return true ;
}
return false ;
}
public bool MoveToNext ( ) {
if ( curNode . NodeType ! = XmlNodeType . Attribute )
return MoveToNextSibling ( curNode ) ;
else
return MoveToNextSibling ( elemNode ) ;
}
public bool MoveToElement ( ) {
if ( this . bCreatedOnAttribute )
return false ;
switch ( curNode . NodeType ) {
case XmlNodeType . Attribute :
if ( elemNode ! = null ) {
curNode = elemNode ;
attrIndex = - 1 ;
return true ;
}
break ;
case XmlNodeType . XmlDeclaration :
case XmlNodeType . DocumentType : {
if ( nAttrInd ! = - 1 ) {
nAttrInd = - 1 ;
return true ;
}
break ;
}
}
return false ;
}
public String LookupNamespace ( string prefix ) {
if ( this . bCreatedOnAttribute )
return null ;
if ( prefix = = "xmlns" ) {
return nameTable . Add ( XmlReservedNs . NsXmlNs ) ;
}
if ( prefix = = "xml" ) {
return nameTable . Add ( XmlReservedNs . NsXml ) ;
}
// construct the name of the xmlns attribute
string attrName ;
if ( prefix = = null )
prefix = string . Empty ;
if ( prefix . Length = = 0 )
attrName = "xmlns" ;
else
attrName = "xmlns:" + prefix ;
// walk up the XmlNode parent chain, looking for the xmlns attribute
XmlNode node = curNode ;
while ( node ! = null ) {
if ( node . NodeType = = XmlNodeType . Element ) {
XmlElement elem = ( XmlElement ) node ;
if ( elem . HasAttributes ) {
XmlAttribute attr = elem . GetAttributeNode ( attrName ) ;
if ( attr ! = null ) {
return attr . Value ;
}
}
}
else if ( node . NodeType = = XmlNodeType . Attribute ) {
node = ( ( XmlAttribute ) node ) . OwnerElement ;
continue ;
}
node = node . ParentNode ;
}
if ( prefix . Length = = 0 ) {
return string . Empty ;
}
return null ;
}
internal string DefaultLookupNamespace ( string prefix ) {
if ( ! this . bCreatedOnAttribute ) {
if ( prefix = = "xmlns" ) {
return nameTable . Add ( XmlReservedNs . NsXmlNs ) ;
}
if ( prefix = = "xml" ) {
return nameTable . Add ( XmlReservedNs . NsXml ) ;
}
if ( prefix = = string . Empty ) {
return nameTable . Add ( string . Empty ) ;
}
}
return null ;
}
internal String LookupPrefix ( string namespaceName ) {
if ( this . bCreatedOnAttribute | | namespaceName = = null ) {
return null ;
}
if ( namespaceName = = XmlReservedNs . NsXmlNs ) {
return nameTable . Add ( "xmlns" ) ;
}
if ( namespaceName = = XmlReservedNs . NsXml ) {
return nameTable . Add ( "xml" ) ;
}
if ( namespaceName = = string . Empty ) {
return string . Empty ;
}
// walk up the XmlNode parent chain, looking for the xmlns attribute with namespaceName value
XmlNode node = curNode ;
while ( node ! = null ) {
if ( node . NodeType = = XmlNodeType . Element ) {
XmlElement elem = ( XmlElement ) node ;
if ( elem . HasAttributes ) {
XmlAttributeCollection attrs = elem . Attributes ;
for ( int i = 0 ; i < attrs . Count ; i + + ) {
XmlAttribute a = attrs [ i ] ;
if ( a . Value = = namespaceName ) {
if ( a . Prefix . Length = = 0 & & a . LocalName = = "xmlns" ) {
if ( LookupNamespace ( string . Empty ) = = namespaceName ) {
return string . Empty ;
}
}
else if ( a . Prefix = = "xmlns" ) {
string pref = a . LocalName ;
if ( LookupNamespace ( pref ) = = namespaceName ) {
return nameTable . Add ( pref ) ;
}
}
}
}
}
}
else if ( node . NodeType = = XmlNodeType . Attribute ) {
node = ( ( XmlAttribute ) node ) . OwnerElement ;
continue ;
}
node = node . ParentNode ;
}
return null ;
}
internal IDictionary < string , string > GetNamespacesInScope ( XmlNamespaceScope scope ) {
Dictionary < string , string > dict = new Dictionary < string , string > ( ) ;
if ( this . bCreatedOnAttribute )
return dict ;
// walk up the XmlNode parent chain and add all namespace declarations to the dictionary
XmlNode node = curNode ;
while ( node ! = null ) {
if ( node . NodeType = = XmlNodeType . Element ) {
XmlElement elem = ( XmlElement ) node ;
if ( elem . HasAttributes ) {
XmlAttributeCollection attrs = elem . Attributes ;
for ( int i = 0 ; i < attrs . Count ; i + + ) {
XmlAttribute a = attrs [ i ] ;
if ( a . LocalName = = "xmlns" & & a . Prefix . Length = = 0 ) {
if ( ! dict . ContainsKey ( string . Empty ) ) {
dict . Add ( nameTable . Add ( string . Empty ) , nameTable . Add ( a . Value ) ) ;
}
}
else if ( a . Prefix = = "xmlns" ) {
string localName = a . LocalName ;
if ( ! dict . ContainsKey ( localName ) ) {
dict . Add ( nameTable . Add ( localName ) , nameTable . Add ( a . Value ) ) ;
}
}
}
}
if ( scope = = XmlNamespaceScope . Local ) {
break ;
}
}
else if ( node . NodeType = = XmlNodeType . Attribute ) {
node = ( ( XmlAttribute ) node ) . OwnerElement ;
continue ;
}
node = node . ParentNode ;
} ;
if ( scope ! = XmlNamespaceScope . Local ) {
if ( dict . ContainsKey ( string . Empty ) & & dict [ string . Empty ] = = string . Empty ) {
dict . Remove ( string . Empty ) ;
}
if ( scope = = XmlNamespaceScope . All ) {
dict . Add ( nameTable . Add ( "xml" ) , nameTable . Add ( XmlReservedNs . NsXml ) ) ;
}
}
return dict ;
}
public bool ReadAttributeValue ( ref int level , ref bool bResolveEntity , ref XmlNodeType nt ) {
if ( nAttrInd ! = - 1 ) {
Debug . Assert ( curNode . NodeType = = XmlNodeType . XmlDeclaration | | curNode . NodeType = = XmlNodeType . DocumentType ) ;
if ( ! this . bOnAttrVal ) {
this . bOnAttrVal = true ;
level + + ;
nt = XmlNodeType . Text ;
return true ;
}
return false ;
}
if ( curNode . NodeType = = XmlNodeType . Attribute ) {
XmlNode firstChild = curNode . FirstChild ;
if ( firstChild ! = null ) {
curNode = firstChild ;
nt = curNode . NodeType ;
level + + ;
this . bOnAttrVal = true ;
return true ;
}
}
else if ( this . bOnAttrVal ) {
XmlNode nextSibling = null ;
if ( curNode . NodeType = = XmlNodeType . EntityReference & & bResolveEntity ) {
//going down to ent ref node
curNode = curNode . FirstChild ;
nt = curNode . NodeType ;
Debug . Assert ( curNode ! = null ) ;
level + + ;
bResolveEntity = false ;
return true ;
}
else
nextSibling = curNode . NextSibling ;
if ( nextSibling = = null ) {
XmlNode parentNode = curNode . ParentNode ;
//Check if its parent is entity ref node is sufficient, because in this senario, ent ref node can't have more than 1 level of children that are not other ent ref nodes
if ( parentNode ! = null & & parentNode . NodeType = = XmlNodeType . EntityReference ) {
//come back from ent ref node
curNode = parentNode ;
nt = XmlNodeType . EndEntity ;
level - - ;
return true ;
}
}
if ( nextSibling ! = null ) {
curNode = nextSibling ;
nt = curNode . NodeType ;
return true ;
}
else
return false ;
}
return false ;
}
public XmlDocument Document {
get {
return this . doc ;
}
}
}
// Represents a reader that provides fast, non-cached forward only stream access
// to XML data in an XmlDocument or a specific XmlNode within an XmlDocument.
public class XmlNodeReader : XmlReader , IXmlNamespaceResolver
{
XmlNodeReaderNavigator readerNav ;
XmlNodeType nodeType ; // nodeType of the node that the reader is currently positioned on
int curDepth ; // depth of attrNav ( also functions as reader's depth )
ReadState readState ; // current reader's state
bool fEOF ; // flag to show if reaches the end of file
//mark to the state that EntityReference node is supposed to be resolved
bool bResolveEntity ;
bool bStartFromDocument ;
bool bInReadBinary ;
ReadContentAsBinaryHelper readBinaryHelper ;
// Creates an instance of the XmlNodeReader class using the specified XmlNode.
public XmlNodeReader ( XmlNode node ) {
if ( node = = null ) {
throw new ArgumentNullException ( "node" ) ;
}
readerNav = new XmlNodeReaderNavigator ( node ) ;
this . curDepth = 0 ;
readState = ReadState . Initial ;
fEOF = false ;
nodeType = XmlNodeType . None ;
bResolveEntity = false ;
bStartFromDocument = false ;
}
//function returns if the reader currently in valid reading states
internal bool IsInReadingStates ( ) {
return ( readState = = ReadState . Interactive ) ; // || readState == ReadState.EndOfFile
}
//
// Node Properties
//
// Gets the type of the current node.
public override XmlNodeType NodeType {
get { return ( IsInReadingStates ( ) ) ? nodeType : XmlNodeType . None ; }
}
// Gets the name of
// the current node, including the namespace prefix.
public override string Name {
get {
if ( ! IsInReadingStates ( ) )
return String . Empty ;
return readerNav . Name ;
}
}
// Gets the name of the current node without the namespace prefix.
public override string LocalName {
get {
if ( ! IsInReadingStates ( ) )
return String . Empty ;
return readerNav . LocalName ;
}
}
// Gets the namespace URN (as defined in the W3C Namespace Specification)
// of the current namespace scope.
public override string NamespaceURI {
get {
if ( ! IsInReadingStates ( ) )
return String . Empty ;
return readerNav . NamespaceURI ;
}
}
// Gets the namespace prefix associated with the current node.
public override string Prefix {
get {
if ( ! IsInReadingStates ( ) )
return String . Empty ;
return readerNav . Prefix ;
}
}
// Gets a value indicating whether
// XmlNodeReader.Value has a value to return.
public override bool HasValue {
get {
if ( ! IsInReadingStates ( ) )
return false ;
return readerNav . HasValue ;
}
}
// Gets the text value of the current node.
public override string Value {
get {
if ( ! IsInReadingStates ( ) )
return String . Empty ;
return readerNav . Value ;
}
}
// Gets the depth of the
// current node in the XML element stack.
public override int Depth {
get { return curDepth ; }
}
// Gets the base URI of the current node.
public override String BaseURI {
get { return readerNav . BaseURI ; }
}
public override bool CanResolveEntity {
get { return true ; }
}
// Gets a value indicating whether the current
// node is an empty element (for example, <MyElement/>.
public override bool IsEmptyElement {
get {
if ( ! IsInReadingStates ( ) )
return false ;
return readerNav . IsEmptyElement ;
}
}
// Gets a value indicating whether the current node is an
// attribute that was generated from the default value defined
// in the DTD or schema.
public override bool IsDefault {
get {
if ( ! IsInReadingStates ( ) )
return false ;
return readerNav . IsDefault ;
}
}
// Gets the current xml:space scope.
public override XmlSpace XmlSpace {
get {
if ( ! IsInReadingStates ( ) )
return XmlSpace . None ;
return readerNav . XmlSpace ;
}
}
// Gets the current xml:lang scope.
public override string XmlLang {
// Assume everything is in Unicode
get {
if ( ! IsInReadingStates ( ) )
return String . Empty ;
return readerNav . XmlLang ;
}
}
public override IXmlSchemaInfo SchemaInfo {
get {
if ( ! IsInReadingStates ( ) ) {
return null ;
}
return readerNav . SchemaInfo ;
}
}
//
// Attribute Accessors
//
// Gets the number of attributes on the current node.
public override int AttributeCount {
get {
if ( ! IsInReadingStates ( ) | | nodeType = = XmlNodeType . EndElement )
return 0 ;
return readerNav . AttributeCount ;
}
}
// Gets the value of the attribute with the specified name.
public override string GetAttribute ( string name ) {
//if not on Attribute, only element node could have attributes
if ( ! IsInReadingStates ( ) )
return null ;
return readerNav . GetAttribute ( name ) ;
}
// Gets the value of the attribute with the specified name and namespace.
public override string GetAttribute ( string name , string namespaceURI ) {
//if not on Attribute, only element node could have attributes
if ( ! IsInReadingStates ( ) )
return null ;
String ns = ( namespaceURI = = null ) ? String . Empty : namespaceURI ;
return readerNav . GetAttribute ( name , ns ) ;
}
// Gets the value of the attribute with the specified index.
public override string GetAttribute ( int attributeIndex ) {
if ( ! IsInReadingStates ( ) )
throw new ArgumentOutOfRangeException ( "attributeIndex" ) ;
//CheckIndexCondition( i );
//Debug.Assert( nav.NodeType == XmlNodeType.Element );
return readerNav . GetAttribute ( attributeIndex ) ;
}
// Moves to the attribute with the specified name.
public override bool MoveToAttribute ( string name ) {
if ( ! IsInReadingStates ( ) )
return false ;
readerNav . ResetMove ( ref curDepth , ref nodeType ) ;
if ( readerNav . MoveToAttribute ( name ) ) { //, ref curDepth ) ) {
curDepth + + ;
nodeType = readerNav . NodeType ;
if ( bInReadBinary ) {
FinishReadBinary ( ) ;
}
return true ;
}
readerNav . RollBackMove ( ref curDepth ) ;
return false ;
}
// Moves to the attribute with the specified name and namespace.
public override bool MoveToAttribute ( string name , string namespaceURI ) {
if ( ! IsInReadingStates ( ) )
return false ;
readerNav . ResetMove ( ref curDepth , ref nodeType ) ;
String ns = ( namespaceURI = = null ) ? String . Empty : namespaceURI ;
if ( readerNav . MoveToAttribute ( name , ns ) ) { //, ref curDepth ) ) {
curDepth + + ;
nodeType = readerNav . NodeType ;
if ( bInReadBinary ) {
FinishReadBinary ( ) ;
}
return true ;
}
readerNav . RollBackMove ( ref curDepth ) ;
return false ;
}
// Moves to the attribute with the specified index.
public override void MoveToAttribute ( int attributeIndex ) {
if ( ! IsInReadingStates ( ) )
throw new ArgumentOutOfRangeException ( "attributeIndex" ) ;
readerNav . ResetMove ( ref curDepth , ref nodeType ) ;
try {
if ( AttributeCount > 0 ) {
readerNav . MoveToAttribute ( attributeIndex ) ;
if ( bInReadBinary ) {
FinishReadBinary ( ) ;
}
}
else
throw new ArgumentOutOfRangeException ( "attributeIndex" ) ;
} catch {
readerNav . RollBackMove ( ref curDepth ) ;
throw ;
}
curDepth + + ;
nodeType = readerNav . NodeType ;
}
// Moves to the first attribute.
public override bool MoveToFirstAttribute ( ) {
if ( ! IsInReadingStates ( ) )
return false ;
readerNav . ResetMove ( ref curDepth , ref nodeType ) ;
if ( AttributeCount > 0 ) {
readerNav . MoveToAttribute ( 0 ) ;
curDepth + + ;
nodeType = readerNav . NodeType ;
if ( bInReadBinary ) {
FinishReadBinary ( ) ;
}
return true ;
}
readerNav . RollBackMove ( ref curDepth ) ;
return false ;
}
// Moves to the next attribute.
public override bool MoveToNextAttribute ( ) {
if ( ! IsInReadingStates ( ) | | nodeType = = XmlNodeType . EndElement )
return false ;
readerNav . LogMove ( curDepth ) ;
readerNav . ResetToAttribute ( ref curDepth ) ;
if ( readerNav . MoveToNextAttribute ( ref curDepth ) ) {
nodeType = readerNav . NodeType ;
if ( bInReadBinary ) {
FinishReadBinary ( ) ;
}
return true ;
}
readerNav . RollBackMove ( ref curDepth ) ;
return false ;
}
// Moves to the element that contains the current attribute node.
public override bool MoveToElement ( ) {
if ( ! IsInReadingStates ( ) )
return false ;
readerNav . LogMove ( curDepth ) ;
readerNav . ResetToAttribute ( ref curDepth ) ;
if ( readerNav . MoveToElement ( ) ) {
curDepth - - ;
nodeType = readerNav . NodeType ;
if ( bInReadBinary ) {
FinishReadBinary ( ) ;
}
return true ;
}
readerNav . RollBackMove ( ref curDepth ) ;
return false ;
}
//
// Moving through the Stream
//
// Reads the next node from the stream.
public override bool Read ( ) {
return Read ( false ) ;
}
private bool Read ( bool fSkipChildren ) {
if ( fEOF )
return false ;
if ( readState = = ReadState . Initial ) {
// if nav is pointing at the document node, start with its children
// otherwise,start with the node.
if ( ( readerNav . NodeType = = XmlNodeType . Document ) | | ( readerNav . NodeType = = XmlNodeType . DocumentFragment ) ) {
bStartFromDocument = true ;
if ( ! ReadNextNode ( fSkipChildren ) ) {
readState = ReadState . Error ;
return false ;
}
}
ReSetReadingMarks ( ) ;
readState = ReadState . Interactive ;
nodeType = readerNav . NodeType ;
//_depth = 0;
curDepth = 0 ;
return true ;
}
if ( bInReadBinary ) {
FinishReadBinary ( ) ;
}
bool bRead = false ;
if ( ( readerNav . CreatedOnAttribute ) )
return false ;
ReSetReadingMarks ( ) ;
bRead = ReadNextNode ( fSkipChildren ) ;
if ( bRead ) {
return true ;
} else {
if ( readState = = ReadState . Initial | | readState = = ReadState . Interactive )
readState = ReadState . Error ;
if ( readState = = ReadState . EndOfFile )
nodeType = XmlNodeType . None ;
return false ;
}
}
private bool ReadNextNode ( bool fSkipChildren ) {
if ( readState ! = ReadState . Interactive & & readState ! = ReadState . Initial ) {
nodeType = XmlNodeType . None ;
return false ;
}
bool bDrillDown = ! fSkipChildren ;
XmlNodeType nt = readerNav . NodeType ;
//only goes down when nav.NodeType is of element or of document at the initial state, other nav.NodeType will not be parsed down
//if nav.NodeType is of EntityReference, ResolveEntity() could be called to get the content parsed;
bDrillDown = bDrillDown
& & ( nodeType ! = XmlNodeType . EndElement )
& & ( nodeType ! = XmlNodeType . EndEntity )
& & ( nt = = XmlNodeType . Element | | ( nt = = XmlNodeType . EntityReference & & bResolveEntity ) | |
( ( ( readerNav . NodeType = = XmlNodeType . Document ) | | ( readerNav . NodeType = = XmlNodeType . DocumentFragment ) ) & & readState = = ReadState . Initial ) ) ;
//first see if there are children of current node, so to move down
if ( bDrillDown ) {
if ( readerNav . MoveToFirstChild ( ) ) {
nodeType = readerNav . NodeType ;
curDepth + + ;
if ( bResolveEntity )
bResolveEntity = false ;
return true ;
} else if ( readerNav . NodeType = = XmlNodeType . Element
& & ! readerNav . IsEmptyElement ) {
nodeType = XmlNodeType . EndElement ;
return true ;
}
else if ( readerNav . NodeType = = XmlNodeType . EntityReference & & bResolveEntity ) {
bResolveEntity = false ;
nodeType = XmlNodeType . EndEntity ;
return true ;
}
// if fails to move to it 1st Child, try to move to next below
return ReadForward ( fSkipChildren ) ;
} else {
if ( readerNav . NodeType = = XmlNodeType . EntityReference & & bResolveEntity ) {
//The only way to get to here is because Skip() is called directly after ResolveEntity()
// in this case, user wants to skip the first Child of EntityRef node and fSkipChildren is true
// We want to pointing to the first child node.
if ( readerNav . MoveToFirstChild ( ) ) {
nodeType = readerNav . NodeType ;
curDepth + + ;
}
else {
nodeType = XmlNodeType . EndEntity ;
}
bResolveEntity = false ;
return true ;
}
}
return ReadForward ( fSkipChildren ) ; //has to get the next node by moving forward
}
private void SetEndOfFile ( ) {
fEOF = true ;
readState = ReadState . EndOfFile ;
nodeType = XmlNodeType . None ;
}
private bool ReadAtZeroLevel ( bool fSkipChildren ) {
Debug . Assert ( curDepth = = 0 ) ;
if ( ! fSkipChildren
& & nodeType ! = XmlNodeType . EndElement
& & readerNav . NodeType = = XmlNodeType . Element
& & ! readerNav . IsEmptyElement ) {
nodeType = XmlNodeType . EndElement ;
return true ;
} else {
SetEndOfFile ( ) ;
return false ;
}
}
private bool ReadForward ( bool fSkipChildren ) {
if ( readState = = ReadState . Error )
return false ;
if ( ! bStartFromDocument & & curDepth = = 0 ) {
//already on top most node and we shouldn't move to next
return ReadAtZeroLevel ( fSkipChildren ) ;
}
//else either we are not on top level or we are starting from the document at the very beginning in which case
// we will need to read all the "top" most nodes
if ( readerNav . MoveToNext ( ) ) {
nodeType = readerNav . NodeType ;
return true ;
} else {
//need to check its parent
if ( curDepth = = 0 )
return ReadAtZeroLevel ( fSkipChildren ) ;
if ( readerNav . MoveToParent ( ) ) {
if ( readerNav . NodeType = = XmlNodeType . Element ) {
curDepth - - ;
nodeType = XmlNodeType . EndElement ;
return true ;
} else if ( readerNav . NodeType = = XmlNodeType . EntityReference ) {
//coming back from entity reference node -- must be getting down through call ResolveEntity()
curDepth - - ;
nodeType = XmlNodeType . EndEntity ;
return true ;
}
return true ;
}
}
return false ;
}
//the function reset the marks used for ReadChars() and MoveToAttribute(...), ReadAttributeValue(...)
private void ReSetReadingMarks ( ) {
//_attrValInd = -1;
readerNav . ResetMove ( ref curDepth , ref nodeType ) ;
//attrNav.MoveTo( nav );
//curDepth = _depth;
}
// Gets a value indicating whether the reader is positioned at the
// end of the stream.
public override bool EOF {
get { return ( readState ! = ReadState . Closed ) & & fEOF ; }
}
// Closes the stream, changes the XmlNodeReader.ReadState
// to Closed, and sets all the properties back to zero.
public override void Close ( ) {
readState = ReadState . Closed ;
}
// Gets the read state of the stream.
public override ReadState ReadState {
get { return readState ; }
}
// Skips to the end tag of the current element.
public override void Skip ( ) {
Read ( true ) ;
}
// Reads the contents of an element as a string.
public override string ReadString ( ) {
if ( ( this . NodeType = = XmlNodeType . EntityReference ) & & bResolveEntity ) {
if ( ! this . Read ( ) ) {
throw new InvalidOperationException ( Res . GetString ( Res . Xml_InvalidOperation ) ) ;
}
}
return base . ReadString ( ) ;
}
//
// Partial Content Read Methods
//
// Gets a value indicating whether the current node
// has any attributes.
public override bool HasAttributes {
get {
return ( AttributeCount > 0 ) ;
}
}
//
// Nametable and Namespace Helpers
//
// Gets the XmlNameTable associated with this implementation.
public override XmlNameTable NameTable {
get { return readerNav . NameTable ; }
}
// Resolves a namespace prefix in the current element's scope.
public override String LookupNamespace ( string prefix ) {
if ( ! IsInReadingStates ( ) )
return null ;
string ns = readerNav . LookupNamespace ( prefix ) ;
if ( ns ! = null & & ns . Length = = 0 ) {
return null ;
}
return ns ;
}
// Resolves the entity reference for nodes of NodeType EntityReference.
public override void ResolveEntity ( ) {
if ( ! IsInReadingStates ( ) | | ( nodeType ! = XmlNodeType . EntityReference ) )
throw new InvalidOperationException ( Res . GetString ( Res . Xnr_ResolveEntity ) ) ;
bResolveEntity = true ; ;
}
// Parses the attribute value into one or more Text and/or
// EntityReference node types.
public override bool ReadAttributeValue ( ) {
if ( ! IsInReadingStates ( ) )
return false ;
if ( readerNav . ReadAttributeValue ( ref curDepth , ref bResolveEntity , ref nodeType ) ) {
bInReadBinary = false ;
return true ;
}
return false ;
}
public override bool CanReadBinaryContent {
get {
return true ;
}
}
public override int ReadContentAsBase64 ( byte [ ] buffer , int index , int count ) {
if ( readState ! = ReadState . Interactive ) {
return 0 ;
}
// init ReadContentAsBinaryHelper when called first time
if ( ! bInReadBinary ) {
readBinaryHelper = ReadContentAsBinaryHelper . CreateOrReset ( readBinaryHelper , this ) ;
}
// turn off bInReadBinary in order to have a normal Read() behavior when called from readBinaryHelper
bInReadBinary = false ;
// call to the helper
int readCount = readBinaryHelper . ReadContentAsBase64 ( buffer , index , count ) ;
// turn on bInReadBinary in again and return
bInReadBinary = true ;
return readCount ;
}
public override int ReadContentAsBinHex ( byte [ ] buffer , int index , int count ) {
if ( readState ! = ReadState . Interactive ) {
return 0 ;
}
// init ReadContentAsBinaryHelper when called first time
if ( ! bInReadBinary ) {
readBinaryHelper = ReadContentAsBinaryHelper . CreateOrReset ( readBinaryHelper , this ) ;
}
// turn off bInReadBinary in order to have a normal Read() behavior when called from readBinaryHelper
bInReadBinary = false ;
// call to the helper
int readCount = readBinaryHelper . ReadContentAsBinHex ( buffer , index , count ) ;
// turn on bInReadBinary in again and return
bInReadBinary = true ;
return readCount ;
}
public override int ReadElementContentAsBase64 ( byte [ ] buffer , int index , int count ) {
if ( readState ! = ReadState . Interactive ) {
return 0 ;
}
// init ReadContentAsBinaryHelper when called first time
if ( ! bInReadBinary ) {
readBinaryHelper = ReadContentAsBinaryHelper . CreateOrReset ( readBinaryHelper , this ) ;
}
// turn off bInReadBinary in order to have a normal Read() behavior when called from readBinaryHelper
bInReadBinary = false ;
// call to the helper
int readCount = readBinaryHelper . ReadElementContentAsBase64 ( buffer , index , count ) ;
// turn on bInReadBinary in again and return
bInReadBinary = true ;
return readCount ;
}
public override int ReadElementContentAsBinHex ( byte [ ] buffer , int index , int count ) {
if ( readState ! = ReadState . Interactive ) {
return 0 ;
}
// init ReadContentAsBinaryHelper when called first time
if ( ! bInReadBinary ) {
readBinaryHelper = ReadContentAsBinaryHelper . CreateOrReset ( readBinaryHelper , this ) ;
}
// turn off bInReadBinary in order to have a normal Read() behavior when called from readBinaryHelper
bInReadBinary = false ;
// call to the helper
int readCount = readBinaryHelper . ReadElementContentAsBinHex ( buffer , index , count ) ;
// turn on bInReadBinary in again and return
bInReadBinary = true ;
return readCount ;
}
void FinishReadBinary ( ) {
bInReadBinary = false ;
readBinaryHelper . Finish ( ) ;
}
//
// IXmlNamespaceResolver
//
IDictionary < string , string > IXmlNamespaceResolver . GetNamespacesInScope ( XmlNamespaceScope scope ) {
return readerNav . GetNamespacesInScope ( scope ) ;
}
string IXmlNamespaceResolver . LookupPrefix ( string namespaceName ) {
return readerNav . LookupPrefix ( namespaceName ) ;
}
String IXmlNamespaceResolver . LookupNamespace ( string prefix ) {
if ( ! IsInReadingStates ( ) ) {
return readerNav . DefaultLookupNamespace ( prefix ) ;
}
string ns = readerNav . LookupNamespace ( prefix ) ;
if ( ns ! = null ) {
ns = readerNav . NameTable . Add ( ns ) ;
}
return ns ;
}
// DTD/Schema info used by XmlReader.GetDtdSchemaInfo()
internal override IDtdInfo DtdInfo {
get {
return readerNav . Document . DtdSchemaInfo ;
}
}
}
}