Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Xml / XmlBaseReader.cs / 1 / XmlBaseReader.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- // PERF, [....], [....]: Make LookupNamespace do something smarter when lots of names // PERF, [....], [....]: Make Attribute lookup smarter when lots of attributes namespace System.Xml { using System; using System.IO; using System.Xml; using System.Collections; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Globalization; using System.Runtime.Serialization; using System.Collections.Generic; using System.Collections.ObjectModel; // Large numbers of attributes // Use delimiter on node for figuring out Element/EndElement? // Optimize StringHandle.CompareTo // Fix FixXmlAttribute - Temporary until we actually write an XmlAttribute node abstract class XmlBaseReader : XmlDictionaryReader { XmlBufferReader bufferReader; XmlNode node; NamespaceManager nsMgr; XmlElementNode[] elementNodes; XmlAttributeNode[] attributeNodes; XmlAtomicTextNode atomicTextNode; int depth; int attributeCount; int attributeStart; // Starting index for searching XmlDictionaryReaderQuotas quotas; XmlNameTable nameTable; XmlDeclarationNode declarationNode; XmlComplexTextNode complexTextNode; XmlWhitespaceTextNode whitespaceTextNode; XmlCDataNode cdataNode; XmlCommentNode commentNode; XmlElementNode rootElementNode; int attributeIndex; // Index for iteration char[] chars; string prefix; string localName; string ns; string value; int trailCharCount; int trailByteCount; char[] trailChars; byte[] trailBytes; bool rootElement; bool readingElement; XmlSigningNodeWriter signingWriter; bool signing; AttributeSorter attributeSorter; static XmlInitialNode initialNode = new XmlInitialNode(XmlBufferReader.Empty); static XmlEndOfFileNode endOfFileNode = new XmlEndOfFileNode(XmlBufferReader.Empty); static XmlClosedNode closedNode = new XmlClosedNode(XmlBufferReader.Empty); static BinHexEncoding binhexEncoding; static Base64Encoding base64Encoding; const string xmlns = "xmlns"; const string xml = "xml"; const string xmlnsNamespace = "http://www.w3.org/2000/xmlns/"; const string xmlNamespace = "http://www.w3.org/XML/1998/namespace"; protected XmlBaseReader() { this.bufferReader = new XmlBufferReader(this); this.nsMgr = new NamespaceManager(bufferReader); this.quotas = new XmlDictionaryReaderQuotas(); this.rootElementNode = new XmlElementNode(bufferReader); this.atomicTextNode = new XmlAtomicTextNode(bufferReader); this.node = closedNode; } static BinHexEncoding BinHexEncoding { get { if (binhexEncoding == null) binhexEncoding = new BinHexEncoding(); return binhexEncoding; } } static Base64Encoding Base64Encoding { get { if (base64Encoding == null) base64Encoding = new Base64Encoding(); return base64Encoding; } } protected XmlBufferReader BufferReader { get { return bufferReader; } } public override XmlDictionaryReaderQuotas Quotas { get { return quotas; } } protected XmlNode Node { get { return node; } } protected void MoveToNode(XmlNode node) { this.node = node; this.ns = null; this.localName = null; this.prefix = null; this.value = null; } protected void MoveToInitial(XmlDictionaryReaderQuotas quotas) { if (quotas == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("quotas"); quotas.InternalCopyTo(this.quotas); this.quotas.MakeReadOnly(); this.nsMgr.Clear(); this.depth = 0; this.attributeCount = 0; this.attributeStart = -1; this.attributeIndex = -1; this.rootElement = false; this.readingElement = false; this.signing = false; MoveToNode(initialNode); } protected XmlDeclarationNode MoveToDeclaration() { if (attributeCount < 1) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlDeclMissingVersion))); if (attributeCount > 3) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); // version if (!CheckDeclAttribute(0, "version", "1.0", false, SR.XmlInvalidVersion)) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlDeclMissingVersion))); // encoding/standalone // We only validate that they are the only attributes that exist. Encoding can have any value. if (attributeCount > 1) { if (CheckDeclAttribute(1, "encoding", null, true, SR.XmlInvalidEncoding)) { if (attributeCount == 3 && !CheckStandalone(2)) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); } else if (!CheckStandalone(1) || attributeCount > 2) { XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); } } if (declarationNode == null) { declarationNode = new XmlDeclarationNode(bufferReader); } MoveToNode(declarationNode); return declarationNode; } bool CheckStandalone(int attr) { XmlAttributeNode node = attributeNodes[attr]; if (!node.Prefix.IsEmpty) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); if (node.LocalName != "standalone") return false; if (!node.Value.Equals2("yes", false) && !node.Value.Equals2("no", false)) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlInvalidStandalone))); return true; } bool CheckDeclAttribute(int index, string localName, string value, bool checkLower, string valueSR) { XmlAttributeNode node = attributeNodes[index]; if (!node.Prefix.IsEmpty) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl))); if (node.LocalName != localName) return false; if (value != null && !node.Value.Equals2(value, checkLower)) XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(valueSR))); return true; } protected XmlCommentNode MoveToComment() { if (commentNode == null) { commentNode = new XmlCommentNode(bufferReader); } MoveToNode(commentNode); return commentNode; } protected XmlCDataNode MoveToCData() { if (cdataNode == null) { this.cdataNode = new XmlCDataNode(bufferReader); } MoveToNode(cdataNode); return cdataNode; } protected XmlAtomicTextNode MoveToAtomicText() { XmlAtomicTextNode textNode = this.atomicTextNode; MoveToNode(textNode); return textNode; } protected XmlComplexTextNode MoveToComplexText() { if (complexTextNode == null) { complexTextNode = new XmlComplexTextNode(bufferReader); } MoveToNode(complexTextNode); return complexTextNode; } protected XmlTextNode MoveToWhitespaceText() { if (whitespaceTextNode == null) { whitespaceTextNode = new XmlWhitespaceTextNode(bufferReader); } if (nsMgr.XmlSpace == XmlSpace.Preserve) whitespaceTextNode.NodeType = XmlNodeType.SignificantWhitespace; else whitespaceTextNode.NodeType = XmlNodeType.Whitespace; MoveToNode(whitespaceTextNode); return whitespaceTextNode; } protected XmlElementNode ElementNode { get { if (depth == 0) return rootElementNode; else return elementNodes[depth]; } } protected void MoveToEndElement() { if (depth == 0) XmlExceptionHelper.ThrowInvalidBinaryFormat(this); XmlElementNode elementNode = elementNodes[depth]; XmlEndElementNode endElementNode = elementNode.EndElement; endElementNode.Namespace = elementNode.Namespace; MoveToNode(endElementNode); } protected void MoveToEndOfFile() { if (depth != 0) XmlExceptionHelper.ThrowUnexpectedEndOfFile(this); MoveToNode(endOfFileNode); } protected XmlElementNode EnterScope() { if (depth == 0) { if (rootElement) XmlExceptionHelper.ThrowMultipleRootElements(this); rootElement = true; } nsMgr.EnterScope(); depth++; if (depth > quotas.MaxDepth) XmlExceptionHelper.ThrowMaxDepthExceeded(this, quotas.MaxDepth); if (elementNodes == null) { elementNodes = new XmlElementNode[4]; } else if (elementNodes.Length == depth) { XmlElementNode[] newElementNodes = new XmlElementNode[depth * 2]; Array.Copy(elementNodes, newElementNodes, depth); elementNodes = newElementNodes; } XmlElementNode elementNode = elementNodes[depth]; if (elementNode == null) { elementNode = new XmlElementNode(bufferReader); elementNodes[depth] = elementNode; } this.attributeCount = 0; this.attributeStart = -1; this.attributeIndex = -1; MoveToNode(elementNode); return elementNode; } protected void ExitScope() { if (depth == 0) XmlExceptionHelper.ThrowUnexpectedEndElement(this); depth--; nsMgr.ExitScope(); } XmlAttributeNode AddAttribute(QNameType qnameType, bool isAtomicValue) { int attributeIndex = this.attributeCount; if (attributeNodes == null) { attributeNodes = new XmlAttributeNode[4]; } else if (attributeNodes.Length == attributeIndex) { XmlAttributeNode[] newAttributeNodes = new XmlAttributeNode[attributeIndex * 2]; Array.Copy(attributeNodes, newAttributeNodes, attributeIndex); attributeNodes = newAttributeNodes; } XmlAttributeNode attributeNode = attributeNodes[attributeIndex]; if (attributeNode == null) { attributeNode = new XmlAttributeNode(bufferReader); attributeNodes[attributeIndex] = attributeNode; } attributeNode.QNameType = qnameType; attributeNode.IsAtomicValue = isAtomicValue; attributeNode.AttributeText.QNameType = qnameType; attributeNode.AttributeText.IsAtomicValue = isAtomicValue; this.attributeCount++; return attributeNode; } protected Namespace AddNamespace() { return nsMgr.AddNamespace(); } protected XmlAttributeNode AddAttribute() { return AddAttribute(QNameType.Normal, true); } protected XmlAttributeNode AddXmlAttribute() { return AddAttribute(QNameType.Normal, true); } protected XmlAttributeNode AddXmlnsAttribute(Namespace ns) { if (!ns.Prefix.IsEmpty && ns.Uri.IsEmpty) XmlExceptionHelper.ThrowEmptyNamespace(this); // Some prefixes can only be bound to a particular namespace if (ns.Prefix.IsXml && ns.Uri != xmlNamespace) { XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlSpecificBindingPrefix, "xml", xmlNamespace))); } else if (ns.Prefix.IsXmlns && ns.Uri != xmlnsNamespace) { XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlSpecificBindingPrefix, "xmlns", xmlnsNamespace))); } nsMgr.Register(ns); XmlAttributeNode attributeNode = AddAttribute(QNameType.Xmlns, false); attributeNode.Namespace = ns; attributeNode.AttributeText.Namespace = ns; return attributeNode; } protected void FixXmlAttribute(XmlAttributeNode attributeNode) { if (attributeNode.Prefix == xml) { if (attributeNode.LocalName == "lang") { nsMgr.AddLangAttribute(attributeNode.Value.GetString()); } else if (attributeNode.LocalName == "space") { string value = attributeNode.Value.GetString(); if (value == "preserve") { nsMgr.AddSpaceAttribute(XmlSpace.Preserve); } else if (value == "default") { nsMgr.AddSpaceAttribute(XmlSpace.Default); } } } } protected bool OutsideRootElement { get { return depth == 0; } } public override bool CanReadBinaryContent { get { return true; } } public override bool CanReadValueChunk { get { return true; } } public override string BaseURI { get { return string.Empty; } } public override bool HasValue { get { return node.HasValue; } } public override bool IsDefault { get { return false; } } public override string this[int index] { get { return GetAttribute(index); } } public override string this[string name] { get { return GetAttribute(name); } } public override string this[string localName, string namespaceUri] { get { return GetAttribute(localName, namespaceUri); } } public override int AttributeCount { get { if (node.CanGetAttribute) return attributeCount; return 0; } } public override void Close() { MoveToNode(closedNode); nameTable = null; if (attributeNodes != null && attributeNodes.Length > 16) attributeNodes = null; if (elementNodes != null && elementNodes.Length > 16) elementNodes = null; nsMgr.Close(); bufferReader.Close(); if (signingWriter != null) signingWriter.Close(); if (attributeSorter != null) attributeSorter.Close(); } public sealed override int Depth { get { // Internally, depth is simply measured by Element/EndElement. What XmlReader exposes is a little different // so we need to account for this with some minor adjustments. // We increment depth immediately when we see an element, but XmlTextReader waits until its consumed // We decrement depth when its consumed, but XmlTextReader decrements depth immediately // If we're on Attribute Text (i.e. ReadAttributeValue), then its considered a level deeper return this.depth + node.DepthDelta; } } public override bool EOF { get { return node.ReadState == ReadState.EndOfFile; } } XmlAttributeNode GetAttributeNode(int index) { if (!node.CanGetAttribute) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.XmlElementAttributes))); if (index < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.ValueMustBeNonNegative))); if (index >= attributeCount) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.OffsetExceedsBufferSize, attributeCount))); return attributeNodes[index]; } XmlAttributeNode GetAttributeNode(string name) { if (name == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name")); if (!node.CanGetAttribute) return null; int index = name.IndexOf(':'); string prefix; string localName; if (index == -1) { if (name == xmlns) { prefix = xmlns; localName = string.Empty; } else { prefix = string.Empty; localName = name; } } else { // If this function becomes a performance issue because of the allocated strings then we can // make a version of Equals that takes an offset and count into the string. prefix = name.Substring(0, index); localName = name.Substring(index + 1); } XmlAttributeNode[] attributeNodes = this.attributeNodes; int attributeCount = this.attributeCount; int attributeIndex = this.attributeStart; for (int i = 0; i < attributeCount; i++) { if (++attributeIndex >= attributeCount) { attributeIndex = 0; } XmlAttributeNode attributeNode = attributeNodes[attributeIndex]; if (attributeNode.IsPrefixAndLocalName(prefix, localName)) { this.attributeStart = attributeIndex; return attributeNode; } } return null; } XmlAttributeNode GetAttributeNode(string localName, string namespaceUri) { if (localName == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName")); if (namespaceUri == null) namespaceUri = string.Empty; if (!node.CanGetAttribute) return null; XmlAttributeNode[] attributeNodes = this.attributeNodes; int attributeCount = this.attributeCount; int attributeIndex = this.attributeStart; for (int i = 0; i < attributeCount; i++) { if (++attributeIndex >= attributeCount) { attributeIndex = 0; } XmlAttributeNode attributeNode = attributeNodes[attributeIndex]; if (attributeNode.IsLocalNameAndNamespaceUri(localName, namespaceUri)) { this.attributeStart = attributeIndex; return attributeNode; } } return null; } XmlAttributeNode GetAttributeNode(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { if (localName == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName")); if (namespaceUri == null) namespaceUri = XmlDictionaryString.Empty; if (!node.CanGetAttribute) return null; XmlAttributeNode[] attributeNodes = this.attributeNodes; int attributeCount = this.attributeCount; int attributeIndex = this.attributeStart; for (int i = 0; i < attributeCount; i++) { if (++attributeIndex >= attributeCount) { attributeIndex = 0; } XmlAttributeNode attributeNode = attributeNodes[attributeIndex]; if (attributeNode.IsLocalNameAndNamespaceUri(localName, namespaceUri)) { this.attributeStart = attributeIndex; return attributeNode; } } return null; } public override string GetAttribute(int index) { return GetAttributeNode(index).ValueAsString; } public override string GetAttribute(string name) { XmlAttributeNode attributeNode = GetAttributeNode(name); if (attributeNode == null) return null; return attributeNode.ValueAsString; } public override string GetAttribute(string localName, string namespaceUri) { XmlAttributeNode attributeNode = GetAttributeNode(localName, namespaceUri); if (attributeNode == null) return null; return attributeNode.ValueAsString; } public override string GetAttribute(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { XmlAttributeNode attributeNode = GetAttributeNode(localName, namespaceUri); if (attributeNode == null) return null; return attributeNode.ValueAsString; } public sealed override bool IsEmptyElement { get { return node.IsEmptyElement; } } public override string LocalName { get { if (localName == null) { QNameType qnameType = node.QNameType; if (qnameType == QNameType.Normal) { localName = node.LocalName.GetString(NameTable); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); if (node.Namespace.Prefix.IsEmpty) localName = xmlns; else localName = node.Namespace.Prefix.GetString(NameTable); } } return localName; } } public override string LookupNamespace(string prefix) { Namespace ns = nsMgr.LookupNamespace(prefix); if (ns != null) return ns.Uri.GetString(NameTable); if (prefix == xmlns) return xmlnsNamespace; return null; } protected Namespace LookupNamespace(PrefixHandleType prefix) { Namespace ns = nsMgr.LookupNamespace(prefix); if (ns == null) XmlExceptionHelper.ThrowUndefinedPrefix(this, PrefixHandle.GetString(prefix)); return ns; } protected Namespace LookupNamespace(PrefixHandle prefix) { Namespace ns = nsMgr.LookupNamespace(prefix); if (ns == null) XmlExceptionHelper.ThrowUndefinedPrefix(this, prefix.GetString()); return ns; } protected void ProcessAttributes() { if (attributeCount > 0) { ProcessAttributes(attributeNodes, attributeCount); } } void ProcessAttributes(XmlAttributeNode[] attributeNodes, int attributeCount) { for (int i = 0; i < attributeCount; i++) { XmlAttributeNode attributeNode = attributeNodes[i]; if (attributeNode.QNameType == QNameType.Normal) { PrefixHandle prefix = attributeNode.Prefix; if (!prefix.IsEmpty) { attributeNode.Namespace = LookupNamespace(prefix); } else { attributeNode.Namespace = NamespaceManager.EmptyNamespace; } attributeNode.AttributeText.Namespace = attributeNode.Namespace; } } if (attributeCount > 1) { if (attributeCount < 12) { // For small numbers of attributes, a naive n * (n - 1) / 2 comparisons to check for uniqueness is faster for (int i = 0; i < attributeCount - 1; i++) { XmlAttributeNode attributeNode1 = attributeNodes[i]; QNameType qnameType = attributeNode1.QNameType; if (qnameType == QNameType.Normal) { for (int j = i + 1; j < attributeCount; j++) { XmlAttributeNode attributeNode2 = attributeNodes[j]; if (attributeNode2.QNameType == QNameType.Normal && attributeNode1.LocalName == attributeNode2.LocalName && attributeNode1.Namespace.Uri == attributeNode2.Namespace.Uri) { XmlExceptionHelper.ThrowDuplicateAttribute(this, attributeNode1.Prefix.GetString(), attributeNode2.Prefix.GetString(), attributeNode1.LocalName.GetString(), attributeNode1.Namespace.Uri.GetString()); } } } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); for (int j = i + 1; j < attributeCount; j++) { XmlAttributeNode attributeNode2 = attributeNodes[j]; if (attributeNode2.QNameType == QNameType.Xmlns && attributeNode1.Namespace.Prefix == attributeNode2.Namespace.Prefix) XmlExceptionHelper.ThrowDuplicateAttribute(this, xmlns, xmlns, attributeNode1.Namespace.Prefix.GetString(), xmlnsNamespace); } } } } else { CheckAttributes(attributeNodes, attributeCount); } } } void CheckAttributes(XmlAttributeNode[] attributeNodes, int attributeCount) { // For large numbers of attributes, sorting the attributes (n * lg(n)) is faster if (attributeSorter == null) attributeSorter = new AttributeSorter(); if (!attributeSorter.Sort(attributeNodes, attributeCount)) { int attribute1, attribute2; attributeSorter.GetIndeces(out attribute1, out attribute2); if (attributeNodes[attribute1].QNameType == QNameType.Xmlns) XmlExceptionHelper.ThrowDuplicateXmlnsAttribute(this, attributeNodes[attribute1].Namespace.Prefix.GetString(), xmlnsNamespace); else XmlExceptionHelper.ThrowDuplicateAttribute(this, attributeNodes[attribute1].Prefix.GetString(), attributeNodes[attribute2].Prefix.GetString(), attributeNodes[attribute1].LocalName.GetString(), attributeNodes[attribute1].Namespace.Uri.GetString()); } } public override void MoveToAttribute(int index) { MoveToNode(GetAttributeNode(index)); } public override bool MoveToAttribute(string name) { XmlNode attributeNode = GetAttributeNode(name); if (attributeNode == null) return false; MoveToNode(attributeNode); return true; } public override bool MoveToAttribute(string localName, string namespaceUri) { XmlNode attributeNode = GetAttributeNode(localName, namespaceUri); if (attributeNode == null) return false; MoveToNode(attributeNode); return true; } public override bool MoveToElement() { if (!node.CanMoveToElement) return false; if (depth == 0) MoveToDeclaration(); else MoveToNode(elementNodes[depth]); this.attributeIndex = -1; return true; } public override XmlNodeType MoveToContent() { do { if (node.HasContent) { if (node.NodeType != XmlNodeType.Text && node.NodeType != XmlNodeType.CDATA) break; if (this.value == null) { if (!node.Value.IsWhitespace()) break; } else { if (!XmlConverter.IsWhitespace(this.value)) break; } } else { if (node.NodeType == XmlNodeType.Attribute) { MoveToElement(); break; } } } while (Read()); return node.NodeType; } public override bool MoveToFirstAttribute() { if (!node.CanGetAttribute || attributeCount == 0) return false; MoveToNode(GetAttributeNode(0)); this.attributeIndex = 0; return true; } public override bool MoveToNextAttribute() { if (!node.CanGetAttribute) return false; int attributeIndex = this.attributeIndex + 1; if (attributeIndex >= attributeCount) return false; MoveToNode(GetAttributeNode(attributeIndex)); this.attributeIndex = attributeIndex; return true; } public override string NamespaceURI { get { if (ns == null) { QNameType qnameType = node.QNameType; if (qnameType == QNameType.Normal) { ns = node.Namespace.Uri.GetString(NameTable); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); ns = xmlnsNamespace; } } return ns; } } public override XmlNameTable NameTable { get { if (nameTable == null) { nameTable = new QuotaNameTable(this, quotas.MaxNameTableCharCount); nameTable.Add(xml); nameTable.Add(xmlns); nameTable.Add(xmlnsNamespace); nameTable.Add(xmlNamespace); for (PrefixHandleType i = PrefixHandleType.A; i <= PrefixHandleType.Z; i++) { nameTable.Add(PrefixHandle.GetString(i)); } } return nameTable; } } public sealed override XmlNodeType NodeType { get { return node.NodeType; } } public override string Prefix { get { if (prefix == null) { QNameType qnameType = node.QNameType; if (qnameType == QNameType.Normal) { prefix = node.Prefix.GetString(NameTable); } else if (qnameType == QNameType.Xmlns) { if (node.Namespace.Prefix.IsEmpty) prefix = string.Empty; else prefix = xmlns; } else { prefix = xml; } } return prefix; } } public override char QuoteChar { get { return node.QuoteChar; } } public override bool IsLocalName(string localName) { if (localName == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName")); return node.IsLocalName(localName); } public override bool IsLocalName(XmlDictionaryString localName) { if (localName == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName")); return node.IsLocalName(localName); } public override bool IsNamespaceUri(string namespaceUri) { if (namespaceUri == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri"); return node.IsNamespaceUri(namespaceUri); } public override bool IsNamespaceUri(XmlDictionaryString namespaceUri) { if (namespaceUri == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri"); return node.IsNamespaceUri(namespaceUri); } public override sealed bool IsStartElement() { XmlNodeType nodeType = node.NodeType; if (nodeType == XmlNodeType.Element) return true; if (nodeType == XmlNodeType.EndElement) return false; if (nodeType == XmlNodeType.None) { Read(); if (node.NodeType == XmlNodeType.Element) return true; } return (MoveToContent() == XmlNodeType.Element); } public override bool IsStartElement(string name) { if (name == null) return false; int index = name.IndexOf(':'); string prefix; string localName; if (index == -1) { prefix = string.Empty; localName = name; } else { prefix = name.Substring(0, index); localName = name.Substring(index + 1); } return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.Prefix == prefix && node.LocalName == localName; } public override bool IsStartElement(string localName, string namespaceUri) { if (localName == null) return false; if (namespaceUri == null) return false; return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.LocalName == localName && node.IsNamespaceUri(namespaceUri); } public override bool IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { if (localName == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName"); if (namespaceUri == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri"); return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.LocalName == localName && node.IsNamespaceUri(namespaceUri); } public override int IndexOfLocalName(string[] localNames, string namespaceUri) { if (localNames == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localNames"); if (namespaceUri == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri"); QNameType qnameType = node.QNameType; if (node.IsNamespaceUri(namespaceUri)) { if (qnameType == QNameType.Normal) { StringHandle localName = node.LocalName; for (int i = 0; i < localNames.Length; i++) { string value = localNames[i]; if (value == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i)); if (localName == value) { return i; } } } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); PrefixHandle prefix = node.Namespace.Prefix; for (int i = 0; i < localNames.Length; i++) { string value = localNames[i]; if (value == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i)); if (prefix == value) { return i; } } } } return -1; } public override int IndexOfLocalName(XmlDictionaryString[] localNames, XmlDictionaryString namespaceUri) { if (localNames == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localNames"); if (namespaceUri == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri"); QNameType qnameType = node.QNameType; if (node.IsNamespaceUri(namespaceUri)) { if (qnameType == QNameType.Normal) { StringHandle localName = node.LocalName; for (int i = 0; i < localNames.Length; i++) { XmlDictionaryString value = localNames[i]; if (value == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i)); if (localName == value) { return i; } } } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); PrefixHandle prefix = node.Namespace.Prefix; for (int i = 0; i < localNames.Length; i++) { XmlDictionaryString value = localNames[i]; if (value == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i)); if (prefix == value) { return i; } } } } return -1; } public override int ReadValueChunk(char[] chars, int offset, int count) { if (chars == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars")); if (offset < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative))); if (offset > chars.Length) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length))); if (count < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative))); if (count > chars.Length - offset) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, chars.Length - offset))); int actual; if (this.value == null) { if (node.QNameType == QNameType.Normal) { if (node.Value.TryReadChars(chars, offset, count, out actual)) return actual; } } string value = this.Value; actual = Math.Min(count, value.Length); value.CopyTo(0, chars, offset, actual); this.value = value.Substring(actual); return actual; } public override int ReadValueAsBase64(byte[] buffer, int offset, int count) { if (buffer == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer")); if (offset < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative))); if (offset > buffer.Length) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length))); if (count < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative))); if (count > buffer.Length - offset) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset))); if (count == 0) return 0; int actual; if (this.value == null) { if (trailByteCount == 0 && trailCharCount == 0) { if (node.QNameType == QNameType.Normal) { if (node.Value.TryReadBase64(buffer, offset, count, out actual)) return actual; } } } return ReadBytes(Base64Encoding, 3, 4, buffer, offset, Math.Min(count, 512), false); } public override string ReadElementContentAsString() { if (node.NodeType != XmlNodeType.Element) MoveToStartElement(); if (node.IsEmptyElement) { Read(); return string.Empty; } else { Read(); string s = ReadContentAsString(); ReadEndElement(); return s; } } public override string ReadElementString() { MoveToStartElement(); if (IsEmptyElement) { Read(); return string.Empty; } else { Read(); string s = ReadString(); ReadEndElement(); return s; } } public override string ReadElementString(string name) { MoveToStartElement(name); return ReadElementString(); } public override string ReadElementString(string localName, string namespaceUri) { MoveToStartElement(localName, namespaceUri); return ReadElementString(); } public override void ReadStartElement() { if (node.NodeType != XmlNodeType.Element) MoveToStartElement(); Read(); } public override void ReadStartElement(string name) { MoveToStartElement(name); Read(); } public override void ReadStartElement(string localName, string namespaceUri) { MoveToStartElement(localName, namespaceUri); Read(); } public override void ReadEndElement() { if (node.NodeType != XmlNodeType.EndElement && MoveToContent() != XmlNodeType.EndElement) { int nodeDepth = node.NodeType == XmlNodeType.Element ? this.depth - 1 : this.depth; if (nodeDepth == 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlEndElementNoOpenNodes))); // If depth is non-zero, then the document isn't what was expected XmlElementNode elementNode = elementNodes[nodeDepth]; XmlExceptionHelper.ThrowEndElementExpected(this, elementNode.LocalName.GetString(), elementNode.Namespace.Uri.GetString()); } Read(); } public override bool ReadAttributeValue() { XmlAttributeTextNode attributeTextNode = node.AttributeText; if (attributeTextNode == null) return false; MoveToNode(attributeTextNode); return true; } public override ReadState ReadState { get { return node.ReadState; } } void SkipValue(XmlNode node) { if (node.SkipValue) Read(); } public override bool TryGetBase64ContentLength(out int length) { if (trailByteCount == 0 && trailCharCount == 0 && this.value == null) { XmlNode node = this.Node; if (node.IsAtomicValue) return node.Value.TryGetByteArrayLength(out length); } return base.TryGetBase64ContentLength(out length); } public override byte[] ReadContentAsBase64() { if (trailByteCount == 0 && trailCharCount == 0 && this.value == null) { XmlNode node = this.Node; if (node.IsAtomicValue) { byte[] value = node.Value.ToByteArray(); if (value.Length > quotas.MaxArrayLength) XmlExceptionHelper.ThrowMaxArrayLengthExceeded(this, quotas.MaxArrayLength); SkipValue(node); return value; } } if (!bufferReader.IsStreamed) return ReadContentAsBase64(quotas.MaxArrayLength, bufferReader.Buffer.Length); return ReadContentAsBase64(quotas.MaxArrayLength, XmlDictionaryReader.MaxInitialArrayLength); // Initial count will get ignored } public override int ReadElementContentAsBase64(byte[] buffer, int offset, int count) { if (!readingElement) { if (IsEmptyElement) { Read(); return 0; } ReadStartElement(); readingElement = true; } int i = ReadContentAsBase64(buffer, offset, count); if (i == 0) { ReadEndElement(); readingElement = false; } return i; } public override int ReadContentAsBase64(byte[] buffer, int offset, int count) { if (buffer == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer")); if (offset < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative))); if (offset > buffer.Length) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length))); if (count < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative))); if (count > buffer.Length - offset) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset))); if (count == 0) return 0; int actual; if (trailByteCount == 0 && trailCharCount == 0 && this.value == null) { if (node.QNameType == QNameType.Normal) { while (node.NodeType != XmlNodeType.Comment && node.Value.TryReadBase64(buffer, offset, count, out actual)) { if (actual != 0) return actual; Read(); } } } XmlNodeType nodeType = node.NodeType; if (nodeType == XmlNodeType.Element || nodeType == XmlNodeType.EndElement) return 0; return ReadBytes(Base64Encoding, 3, 4, buffer, offset, Math.Min(count, 512), true); } public override byte[] ReadContentAsBinHex() { return ReadContentAsBinHex(quotas.MaxArrayLength); } public override int ReadElementContentAsBinHex(byte[] buffer, int offset, int count) { if (!readingElement) { if (IsEmptyElement) { Read(); return 0; } ReadStartElement(); readingElement = true; } int i = ReadContentAsBinHex(buffer, offset, count); if (i == 0) { ReadEndElement(); readingElement = false; } return i; } public override int ReadContentAsBinHex(byte[] buffer, int offset, int count) { if (buffer == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer")); if (offset < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative))); if (offset > buffer.Length) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length))); if (count < 0) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative))); if (count > buffer.Length - offset) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset))); if (count == 0) return 0; return ReadBytes(BinHexEncoding, 1, 2, buffer, offset, Math.Min(count, 512), true); } int ReadBytes(Encoding encoding, int byteBlock, int charBlock, byte[] buffer, int offset, int byteCount, bool readContent) { // If there are any trailing buffer return them. if (trailByteCount > 0) { int actual = Math.Min(trailByteCount, byteCount); Array.Copy(trailBytes, 0, buffer, offset, actual); trailByteCount -= actual; Array.Copy(trailBytes, actual, trailBytes, 0, trailByteCount); return actual; } XmlNodeType nodeType = node.NodeType; if (nodeType == XmlNodeType.Element || nodeType == XmlNodeType.EndElement) return 0; int maxCharCount; if (byteCount < byteBlock) { // Convert at least charBlock chars maxCharCount = charBlock; } else { // Round down to the nearest multiple of charBlock maxCharCount = byteCount / byteBlock * charBlock; } char[] chars = GetCharBuffer(maxCharCount); int charCount = 0; while (true) { // If we didn't align on the boundary, then we might have some remaining characters if (trailCharCount > 0) { Array.Copy(trailChars, 0, chars, charCount, trailCharCount); charCount += trailCharCount; trailCharCount = 0; } // Read until we at least get a charBlock while (charCount < charBlock) { int actualCharCount; if (readContent) actualCharCount = ReadContentAsChars(chars, charCount, maxCharCount - charCount); else actualCharCount = ReadValueChunk(chars, charCount, maxCharCount - charCount); if (actualCharCount == 0) break; charCount += actualCharCount; } // Trim so its a multiple of charBlock if (charCount >= charBlock) { trailCharCount = (charCount % charBlock); if (trailCharCount > 0) { if (trailChars == null) trailChars = new char[4]; charCount = charCount - trailCharCount; Array.Copy(chars, charCount, trailChars, 0, trailCharCount); } } try { if (byteCount < byteBlock) { if (trailBytes == null) trailBytes = new byte[3]; trailByteCount = encoding.GetBytes(chars, 0, charCount, trailBytes, 0); int actual = Math.Min(trailByteCount, byteCount); Array.Copy(trailBytes, 0, buffer, offset, actual); trailByteCount -= actual; Array.Copy(trailBytes, actual, trailBytes, 0, trailByteCount); return actual; } else { // charCount is a multiple of charBlock and we have enough room to convert everything return encoding.GetBytes(chars, 0, charCount, buffer, offset); } } catch (FormatException exception) { // Something was wrong with the format, see if we can strip the spaces int i = 0; int j = 0; while (true) { while (j < charCount && XmlConverter.IsWhitespace(chars[j])) j++; if (j == charCount) break; chars[i++] = chars[j++]; } // No spaces, so don't try again if (i == charCount) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(exception.Message, exception.InnerException)); charCount = i; } } } public override string ReadContentAsString() { string value; XmlNode node = this.Node; if (node.IsAtomicValue) { if (this.value != null) { value = this.value; if (node.AttributeText == null) this.value = string.Empty; } else { value = node.Value.GetString(); SkipValue(node); if (value.Length > quotas.MaxStringContentLength) XmlExceptionHelper.ThrowMaxStringContentLengthExceeded(this, quotas.MaxStringContentLength); } return value; } return base.ReadContentAsString(quotas.MaxStringContentLength); } public override Boolean ReadContentAsBoolean() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { bool value = node.Value.ToBoolean(); SkipValue(node); return value; } return XmlConverter.ToBoolean(ReadContentAsString()); } public override Int64 ReadContentAsLong() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { Int64 value = node.Value.ToLong(); SkipValue(node); return value; } return XmlConverter.ToInt64(ReadContentAsString()); } public override Int32 ReadContentAsInt() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { Int32 value = node.Value.ToInt(); SkipValue(node); return value; } return XmlConverter.ToInt32(ReadContentAsString()); } public override DateTime ReadContentAsDateTime() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { DateTime value = node.Value.ToDateTime(); SkipValue(node); return value; } return XmlConverter.ToDateTime(ReadContentAsString()); } public override Double ReadContentAsDouble() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { double value = node.Value.ToDouble(); SkipValue(node); return value; } return XmlConverter.ToDouble(ReadContentAsString()); } public override Single ReadContentAsFloat() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { float value = node.Value.ToSingle(); SkipValue(node); return value; } return XmlConverter.ToSingle(ReadContentAsString()); } public override Decimal ReadContentAsDecimal() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { decimal value = node.Value.ToDecimal(); SkipValue(node); return value; } return XmlConverter.ToDecimal(ReadContentAsString()); } public override UniqueId ReadContentAsUniqueId() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { UniqueId value = node.Value.ToUniqueId(); SkipValue(node); return value; } return XmlConverter.ToUniqueId(ReadContentAsString()); } public override TimeSpan ReadContentAsTimeSpan() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { TimeSpan value = node.Value.ToTimeSpan(); SkipValue(node); return value; } return XmlConverter.ToTimeSpan(ReadContentAsString()); } public override Guid ReadContentAsGuid() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { Guid value = node.Value.ToGuid(); SkipValue(node); return value; } return XmlConverter.ToGuid(ReadContentAsString()); } public override object ReadContentAsObject() { XmlNode node = this.Node; if (this.value == null && node.IsAtomicValue) { object obj = node.Value.ToObject(); SkipValue(node); return obj; } return ReadContentAsString(); } public override object ReadContentAs(Type type, IXmlNamespaceResolver namespaceResolver) { if (type == typeof(ulong)) { if (this.value == null && node.IsAtomicValue) { ulong value = node.Value.ToULong(); SkipValue(node); return value; } else { return XmlConverter.ToUInt64(ReadContentAsString()); } } else if (type == typeof(bool)) return ReadContentAsBoolean(); else if (type == typeof(int)) return ReadContentAsInt(); else if (type == typeof(long)) return ReadContentAsLong(); else if (type == typeof(float)) return ReadContentAsFloat(); else if (type == typeof(double)) return ReadContentAsDouble(); else if (type == typeof(decimal)) return ReadContentAsDecimal(); else if (type == typeof(DateTime)) return ReadContentAsDateTime(); else if (type == typeof(UniqueId)) return ReadContentAsUniqueId(); else if (type == typeof(Guid)) return ReadContentAsGuid(); else if (type == typeof(TimeSpan)) return ReadContentAsTimeSpan(); else if (type == typeof(object)) return ReadContentAsObject(); else return base.ReadContentAs(type, namespaceResolver); } public override void ResolveEntity() { throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlInvalidOperation))); } public override void Skip() { if (node.ReadState != ReadState.Interactive) return; if ((node.NodeType == XmlNodeType.Element || MoveToElement()) && !IsEmptyElement) { int depth = Depth; while (Read() && depth < Depth) { // Nothing, just read on } // consume end tag if (node.NodeType == XmlNodeType.EndElement) Read(); } else { Read(); } } public override string Value { get { if (value == null) { value = node.ValueAsString; } return value; } } public override Type ValueType { get { if (this.value == null && node.QNameType == QNameType.Normal) { Type type = node.Value.ToType(); if (node.IsAtomicValue) return type; if (type == typeof(byte[])) return type; } return typeof(string); } } public override string XmlLang { get { return nsMgr.XmlLang; } } public override XmlSpace XmlSpace { get { return nsMgr.XmlSpace; } } public override bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName) { return node.TryGetLocalNameAsDictionaryString(out localName); } public override bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString localName) { return node.TryGetNamespaceUriAsDictionaryString(out localName); } public override bool TryGetValueAsDictionaryString(out XmlDictionaryString value) { return node.TryGetValueAsDictionaryString(out value); } public override Int16[] ReadInt16Array(string localName, string namespaceUri) { return Int16ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override Int16[] ReadInt16Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return Int16ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override Int32[] ReadInt32Array(string localName, string namespaceUri) { return Int32ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override Int32[] ReadInt32Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return Int32ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override Int64[] ReadInt64Array(string localName, string namespaceUri) { return Int64ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override Int64[] ReadInt64Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return Int64ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override float[] ReadSingleArray(string localName, string namespaceUri) { return SingleArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override float[] ReadSingleArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return SingleArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override double[] ReadDoubleArray(string localName, string namespaceUri) { return DoubleArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override double[] ReadDoubleArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return DoubleArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override decimal[] ReadDecimalArray(string localName, string namespaceUri) { return DecimalArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override decimal[] ReadDecimalArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return DecimalArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override DateTime[] ReadDateTimeArray(string localName, string namespaceUri) { return DateTimeArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override DateTime[] ReadDateTimeArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return DateTimeArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override Guid[] ReadGuidArray(string localName, string namespaceUri) { return GuidArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override Guid[] ReadGuidArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return GuidArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override TimeSpan[] ReadTimeSpanArray(string localName, string namespaceUri) { return TimeSpanArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public override TimeSpan[] ReadTimeSpanArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri) { return TimeSpanArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength); } public string GetOpenElements() { string s = string.Empty; for (int i = depth; i > 0; i--) { string localName = elementNodes[i].LocalName.GetString(); if (i != depth) s += ", "; s += localName; } return s; } char[] GetCharBuffer(int count) { if (count > 1024) return new char[count]; if (chars == null || chars.Length < count) chars = new char[count]; return chars; } void SignStartElement(XmlSigningNodeWriter writer) { int prefixOffset, prefixLength; byte[] prefixBuffer = node.Prefix.GetString(out prefixOffset, out prefixLength); int localNameOffset, localNameLength; byte[] localNameBuffer = node.LocalName.GetString(out localNameOffset, out localNameLength); writer.WriteStartElement(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength); } void SignAttribute(XmlSigningNodeWriter writer, XmlAttributeNode attributeNode) { QNameType qnameType = attributeNode.QNameType; if (qnameType == QNameType.Normal) { int prefixOffset, prefixLength; byte[] prefixBuffer = attributeNode.Prefix.GetString(out prefixOffset, out prefixLength); int localNameOffset, localNameLength; byte[] localNameBuffer = attributeNode.LocalName.GetString(out localNameOffset, out localNameLength); writer.WriteStartAttribute(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength); attributeNode.Value.Sign(writer); writer.WriteEndAttribute(); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); int prefixOffset, prefixLength; byte[] prefixBuffer = attributeNode.Namespace.Prefix.GetString(out prefixOffset, out prefixLength); int nsOffset, nsLength; byte[] nsBuffer = attributeNode.Namespace.Uri.GetString(out nsOffset, out nsLength); writer.WriteXmlnsAttribute(prefixBuffer, prefixOffset, prefixLength, nsBuffer, nsOffset, nsLength); } } void SignEndElement(XmlSigningNodeWriter writer) { int prefixOffset, prefixLength; byte[] prefixBuffer = node.Prefix.GetString(out prefixOffset, out prefixLength); int localNameOffset, localNameLength; byte[] localNameBuffer = node.LocalName.GetString(out localNameOffset, out localNameLength); writer.WriteEndElement(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength); } void SignNode(XmlSigningNodeWriter writer) { switch (node.NodeType) { case XmlNodeType.None: break; case XmlNodeType.Element: SignStartElement(writer); for (int i = 0; i < attributeCount; i++) SignAttribute(writer, attributeNodes[i]); writer.WriteEndStartElement(node.IsEmptyElement); break; case XmlNodeType.Text: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: case XmlNodeType.CDATA: node.Value.Sign(writer); break; case XmlNodeType.XmlDeclaration: writer.WriteDeclaration(); break; case XmlNodeType.Comment: writer.WriteComment(node.Value.GetString()); break; case XmlNodeType.EndElement: SignEndElement(writer); break; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException()); } } public override bool CanCanonicalize { get { return true; } } protected bool Signing { get { return signing; } } protected void SignNode() { if (signing) { SignNode(signingWriter); } } public override void StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes) { if (signing) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlCanonicalizationStarted))); if (signingWriter == null) signingWriter = CreateSigningNodeWriter(); signingWriter.SetOutput(XmlNodeWriter.Null, stream, includeComments, inclusivePrefixes); nsMgr.Sign(signingWriter); signing = true; } public override void EndCanonicalization() { if (!signing) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlCanonicalizationNotStarted))); signingWriter.Flush(); signingWriter.Close(); signing = false; } protected abstract XmlSigningNodeWriter CreateSigningNodeWriter(); protected enum QNameType { Normal, Xmlns, } protected class XmlNode { XmlNodeType nodeType; PrefixHandle prefix; StringHandle localName; ValueHandle value; Namespace ns; bool hasValue; bool canGetAttribute; bool canMoveToElement; ReadState readState; XmlAttributeTextNode attributeTextNode; bool exitScope; int depthDelta; bool isAtomicValue; bool skipValue; QNameType qnameType; bool hasContent; bool isEmptyElement; char quoteChar; protected enum XmlNodeFlags { None = 0x00, CanGetAttribute = 0x01, CanMoveToElement = 0x02, HasValue = 0x04, AtomicValue = 0x08, SkipValue = 0x10, HasContent = 0x20 } protected XmlNode(XmlNodeType nodeType, PrefixHandle prefix, StringHandle localName, ValueHandle value, XmlNodeFlags nodeFlags, ReadState readState, XmlAttributeTextNode attributeTextNode, int depthDelta) { this.nodeType = nodeType; this.prefix = prefix; this.localName = localName; this.value = value; this.ns = NamespaceManager.EmptyNamespace; this.hasValue = ((nodeFlags & XmlNodeFlags.HasValue) != 0); this.canGetAttribute = ((nodeFlags & XmlNodeFlags.CanGetAttribute) != 0); this.canMoveToElement = ((nodeFlags & XmlNodeFlags.CanMoveToElement) != 0); this.isAtomicValue = ((nodeFlags & XmlNodeFlags.AtomicValue) != 0); this.skipValue = ((nodeFlags & XmlNodeFlags.SkipValue) != 0); this.hasContent = ((nodeFlags & XmlNodeFlags.HasContent) != 0); this.readState = readState; this.attributeTextNode = attributeTextNode; this.exitScope = (nodeType == XmlNodeType.EndElement); this.depthDelta = depthDelta; this.isEmptyElement = false; this.quoteChar = '"'; this.qnameType = QNameType.Normal; } // Most nodes are read-only and fixed for the particular node type, but a few need to be tweaked // QNameType needs to get set for all nodes with a qname (Element/Attribute) // NodeType gets set for WhiteSpace vs. SignificantWhitespace // ExitScope/IsEmptyElement is only updated by text for empty elements // QuoteChar is only updated by text for attributes // IsAtomicValue is set to false for XmlnsAttributes so we don't have to check QNameType public bool HasValue { get { return hasValue; } } public ReadState ReadState { get { return readState; } } public StringHandle LocalName { get { DiagnosticUtility.DebugAssert(qnameType != QNameType.Xmlns, ""); return localName; } } public PrefixHandle Prefix { get { DiagnosticUtility.DebugAssert(qnameType != QNameType.Xmlns, ""); return prefix; } } public bool CanGetAttribute { get { return canGetAttribute; } } public bool CanMoveToElement { get { return canMoveToElement; } } public XmlAttributeTextNode AttributeText { get { return attributeTextNode; } } public bool SkipValue { get { return skipValue; } } public ValueHandle Value { get { DiagnosticUtility.DebugAssert(qnameType != QNameType.Xmlns, ""); return value; } } public int DepthDelta { get { return depthDelta; } } public bool HasContent { get { return hasContent; } } public XmlNodeType NodeType { get { return nodeType; } set { nodeType = value; } } public QNameType QNameType { get { return qnameType; } set { qnameType = value; } } public Namespace Namespace { get { return ns; } set { ns = value; } } public bool IsAtomicValue { get { return isAtomicValue; } set { isAtomicValue = value; } } public bool ExitScope { get { return exitScope; } set { exitScope = value; } } public bool IsEmptyElement { get { return isEmptyElement; } set { isEmptyElement = value; } } public char QuoteChar { get { return quoteChar; } set { quoteChar = value; } } public bool IsLocalName(string localName) { if (qnameType == QNameType.Normal) { return this.LocalName == localName; } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return this.Namespace.Prefix == localName; } } public bool IsLocalName(XmlDictionaryString localName) { if (qnameType == QNameType.Normal) { return this.LocalName == localName; } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return this.Namespace.Prefix == localName; } } public bool IsNamespaceUri(string ns) { if (qnameType == QNameType.Normal) { return this.Namespace.IsUri(ns); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return ns == xmlnsNamespace; } } public bool IsNamespaceUri(XmlDictionaryString ns) { if (qnameType == QNameType.Normal) { return this.Namespace.IsUri(ns); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return ns.Value == xmlnsNamespace; } } public bool IsLocalNameAndNamespaceUri(string localName, string ns) { if (qnameType == QNameType.Normal) { return this.LocalName == localName && this.Namespace.IsUri(ns); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return this.Namespace.Prefix == localName && ns == xmlnsNamespace; } } public bool IsLocalNameAndNamespaceUri(XmlDictionaryString localName, XmlDictionaryString ns) { if (qnameType == QNameType.Normal) { return this.LocalName == localName && this.Namespace.IsUri(ns); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return this.Namespace.Prefix == localName && ns.Value == xmlnsNamespace; } } public bool IsPrefixAndLocalName(string prefix, string localName) { if (qnameType == QNameType.Normal) { return this.Prefix == prefix && this.LocalName == localName; } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return prefix == xmlns && this.Namespace.Prefix == localName; } } public bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName) { if (qnameType == QNameType.Normal) { return this.LocalName.TryGetDictionaryString(out localName); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); localName = null; return false; } } public bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString ns) { if (qnameType == QNameType.Normal) { return this.Namespace.Uri.TryGetDictionaryString(out ns); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); ns = null; return false; } } public bool TryGetValueAsDictionaryString(out XmlDictionaryString value) { if (qnameType == QNameType.Normal) { return this.Value.TryGetDictionaryString(out value); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); value = null; return false; } } public string ValueAsString { get { if (qnameType == QNameType.Normal) { return Value.GetString(); } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); return Namespace.Uri.GetString(); } } } } protected class XmlElementNode : XmlNode { XmlEndElementNode endElementNode; int bufferOffset; public XmlElementNode(XmlBufferReader bufferReader) : this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader)) { } XmlElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value) : base(XmlNodeType.Element, prefix, localName, value, XmlNodeFlags.CanGetAttribute|XmlNodeFlags.HasContent, ReadState.Interactive, null, -1) { this.endElementNode = new XmlEndElementNode(prefix, localName, value); } public XmlEndElementNode EndElement { get { return endElementNode; } } public int BufferOffset { get { return bufferOffset; } set { bufferOffset = value; } } public int NameOffset; public int NameLength; } protected class XmlAttributeNode : XmlNode { public XmlAttributeNode(XmlBufferReader bufferReader) : this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader)) { } XmlAttributeNode(PrefixHandle prefix, StringHandle localName, ValueHandle value) : base(XmlNodeType.Attribute, prefix, localName, value, XmlNodeFlags.CanGetAttribute|XmlNodeFlags.CanMoveToElement|XmlNodeFlags.HasValue|XmlNodeFlags.AtomicValue, ReadState.Interactive, new XmlAttributeTextNode(prefix, localName, value), 0) { } } protected class XmlEndElementNode : XmlNode { public XmlEndElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value) : base(XmlNodeType.EndElement, prefix, localName, value, XmlNodeFlags.HasContent, ReadState.Interactive, null, -1) { } } protected class XmlTextNode : XmlNode { protected XmlTextNode(XmlNodeType nodeType, PrefixHandle prefix, StringHandle localName, ValueHandle value, XmlNodeFlags nodeFlags, ReadState readState, XmlAttributeTextNode attributeTextNode, int depthDelta) : base(nodeType, prefix, localName, value, nodeFlags, readState, attributeTextNode, depthDelta) { } } protected class XmlAtomicTextNode : XmlTextNode { public XmlAtomicTextNode(XmlBufferReader bufferReader) : base(XmlNodeType.Text, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue | XmlNodeFlags.AtomicValue | XmlNodeFlags.SkipValue | XmlNodeFlags.HasContent, ReadState.Interactive, null, 0) { } } protected class XmlComplexTextNode : XmlTextNode { public XmlComplexTextNode(XmlBufferReader bufferReader) : base(XmlNodeType.Text, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue | XmlNodeFlags.HasContent, ReadState.Interactive, null, 0) { } } protected class XmlWhitespaceTextNode : XmlTextNode { public XmlWhitespaceTextNode(XmlBufferReader bufferReader) : base(XmlNodeType.Whitespace, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue, ReadState.Interactive, null, 0) { } } protected class XmlCDataNode : XmlTextNode { public XmlCDataNode(XmlBufferReader bufferReader) : base(XmlNodeType.CDATA, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue | XmlNodeFlags.HasContent, ReadState.Interactive, null, 0) { } } protected class XmlAttributeTextNode : XmlTextNode { public XmlAttributeTextNode(PrefixHandle prefix, StringHandle localName, ValueHandle value) : base(XmlNodeType.Text, prefix, localName, value, XmlNodeFlags.HasValue|XmlNodeFlags.CanGetAttribute|XmlNodeFlags.CanMoveToElement|XmlNodeFlags.AtomicValue|XmlNodeFlags.HasContent, ReadState.Interactive, null, 1) { } } protected class XmlInitialNode : XmlNode { public XmlInitialNode(XmlBufferReader bufferReader) : base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.Initial, null, 0) { } } protected class XmlDeclarationNode : XmlNode { public XmlDeclarationNode(XmlBufferReader bufferReader) : base(XmlNodeType.XmlDeclaration, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.CanGetAttribute, ReadState.Interactive, null, 0) { } } protected class XmlCommentNode : XmlNode { public XmlCommentNode(XmlBufferReader bufferReader) : base(XmlNodeType.Comment, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue, ReadState.Interactive, null, 0) { } } protected class XmlEndOfFileNode : XmlNode { public XmlEndOfFileNode(XmlBufferReader bufferReader) : base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.EndOfFile, null, 0) { } } protected class XmlClosedNode : XmlNode { public XmlClosedNode(XmlBufferReader bufferReader) : base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.Closed, null, 0) { } } class AttributeSorter : IComparer { object[] indeces; XmlAttributeNode[] attributeNodes; int attributeCount; int attributeIndex1; int attributeIndex2; public bool Sort(XmlAttributeNode[] attributeNodes, int attributeCount) { this.attributeIndex1 = -1; this.attributeIndex2 = -1; this.attributeNodes = attributeNodes; this.attributeCount = attributeCount; bool sorted = Sort(); this.attributeNodes = null; this.attributeCount = 0; return sorted; } public void GetIndeces(out int attributeIndex1, out int attributeIndex2) { attributeIndex1 = this.attributeIndex1; attributeIndex2 = this.attributeIndex2; } public void Close() { if (indeces != null && indeces.Length > 32) { indeces = null; } } bool Sort() { // Optimistically use the last sort order and check to see if that works. This helps the case // where elements with large numbers of attributes are repeated. if (indeces != null && indeces.Length == attributeCount && IsSorted()) return true; object[] newIndeces = new object[attributeCount]; for (int i = 0; i < newIndeces.Length; i++) newIndeces[i] = i; this.indeces = newIndeces; Array.Sort(indeces, 0, attributeCount, this); return IsSorted(); } bool IsSorted() { for (int i = 0; i < indeces.Length - 1; i++) { if (Compare(indeces[i], indeces[i + 1]) >= 0) { attributeIndex1 = (int)indeces[i]; attributeIndex2 = (int)indeces[i + 1]; return false; } } return true; } public int Compare(object obj1, object obj2) { int index1 = (int)obj1; int index2 = (int)obj2; XmlAttributeNode attribute1 = attributeNodes[index1]; XmlAttributeNode attribute2 = attributeNodes[index2]; int i = CompareQNameType(attribute1.QNameType, attribute2.QNameType); if (i == 0) { QNameType qnameType = attribute1.QNameType; if (qnameType == QNameType.Normal) { i = attribute1.LocalName.CompareTo(attribute2.LocalName); if (i == 0) { i = attribute1.Namespace.Uri.CompareTo(attribute2.Namespace.Uri); } } else { DiagnosticUtility.DebugAssert(qnameType == QNameType.Xmlns, ""); i = attribute1.Namespace.Prefix.CompareTo(attribute2.Namespace.Prefix); } } return i; } public int CompareQNameType(QNameType type1, QNameType type2) { return (int)type1 - (int)type2; } } class NamespaceManager { XmlBufferReader bufferReader; Namespace[] namespaces; int nsCount; int depth; Namespace[] shortPrefixUri; static Namespace emptyNamespace = new Namespace(XmlBufferReader.Empty); static Namespace xmlNamespace; XmlAttribute[] attributes; int attributeCount; XmlSpace space; string lang; public NamespaceManager(XmlBufferReader bufferReader) { this.bufferReader = bufferReader; this.shortPrefixUri = new Namespace[(int)PrefixHandleType.Max]; this.shortPrefixUri[(int)PrefixHandleType.Empty] = emptyNamespace; this.namespaces = null; this.nsCount = 0; this.attributes = null; this.attributeCount = 0; this.space = XmlSpace.None; this.lang = string.Empty; this.depth = 0; } public void Close() { if (namespaces != null && namespaces.Length > 32) namespaces = null; if (attributes != null && attributes.Length > 4) attributes = null; lang = string.Empty; } static public Namespace XmlNamespace { get { if (xmlNamespace == null) { byte[] xmlBuffer = { (byte)'x',(byte)'m',(byte)'l', (byte)'h',(byte)'t',(byte)'t',(byte)'p',(byte)':',(byte)'/',(byte)'/',(byte)'w', (byte)'w',(byte)'w',(byte)'.',(byte)'w',(byte)'3',(byte)'.',(byte)'o',(byte)'r', (byte)'g',(byte)'/',(byte)'X',(byte)'M',(byte)'L',(byte)'/',(byte)'1',(byte)'9', (byte)'9',(byte)'8',(byte)'/',(byte)'n',(byte)'a',(byte)'m',(byte)'e',(byte)'s', (byte)'p',(byte)'a',(byte)'c',(byte)'e' }; Namespace nameSpace = new Namespace(new XmlBufferReader(xmlBuffer)); nameSpace.Prefix.SetValue(0, 3); nameSpace.Uri.SetValue(3, xmlBuffer.Length - 3); xmlNamespace = nameSpace; } return xmlNamespace; } } static public Namespace EmptyNamespace { get { return emptyNamespace; } } public string XmlLang { get { return lang; } } public XmlSpace XmlSpace { get { return space; } } public void Clear() { if (nsCount != 0) { if (shortPrefixUri != null) { for (int i = 0; i < shortPrefixUri.Length; i++) { shortPrefixUri[i] = null; } } shortPrefixUri[(int)PrefixHandleType.Empty] = emptyNamespace; nsCount = 0; } this.attributeCount = 0; this.space = XmlSpace.None; this.lang = string.Empty; this.depth = 0; } public void EnterScope() { depth++; } public void ExitScope() { while (nsCount > 0) { Namespace nameSpace = namespaces[nsCount - 1]; if (nameSpace.Depth != depth) break; PrefixHandleType shortPrefix; if (nameSpace.Prefix.TryGetShortPrefix(out shortPrefix)) { shortPrefixUri[(int)shortPrefix] = nameSpace.OuterUri; } nsCount--; } while (attributeCount > 0) { XmlAttribute attribute = attributes[attributeCount - 1]; if (attribute.Depth != depth) break; space = attribute.XmlSpace; lang = attribute.XmlLang; attributeCount--; } depth--; } public void Sign(XmlSigningNodeWriter writer) { for (int i = 0; i < nsCount; i++) { PrefixHandle prefix = namespaces[i].Prefix; bool found = false; for (int j = i + 1; j < nsCount; j++) { if (Equals(prefix, namespaces[j].Prefix)) { found = true; break; } } if (!found) { int prefixOffset, prefixLength; byte[] prefixBuffer = prefix.GetString(out prefixOffset, out prefixLength); int nsOffset, nsLength; byte[] nsBuffer = namespaces[i].Uri.GetString(out nsOffset, out nsLength); writer.WriteXmlnsAttribute(prefixBuffer, prefixOffset, prefixLength, nsBuffer, nsOffset, nsLength); } } } public void AddLangAttribute(string lang) { AddAttribute(); this.lang = lang; } public void AddSpaceAttribute(XmlSpace space) { AddAttribute(); this.space = space; } void AddAttribute() { if (attributes == null) { attributes = new XmlAttribute[1]; } else if (attributes.Length == attributeCount) { XmlAttribute[] newAttributes = new XmlAttribute[attributeCount * 2]; Array.Copy(attributes, newAttributes, attributeCount); attributes = newAttributes; } XmlAttribute attribute = attributes[attributeCount]; if (attribute == null) { attribute = new XmlAttribute(); attributes[attributeCount] = attribute; } attribute.XmlLang = this.lang; attribute.XmlSpace = this.space; attribute.Depth = depth; attributeCount++; } public void Register(Namespace nameSpace) { PrefixHandleType shortPrefix; if (nameSpace.Prefix.TryGetShortPrefix(out shortPrefix)) { nameSpace.OuterUri = shortPrefixUri[(int)shortPrefix]; shortPrefixUri[(int)shortPrefix] = nameSpace; } else { nameSpace.OuterUri = null; } } public Namespace AddNamespace() { if (namespaces == null) { namespaces = new Namespace[4]; } else if (namespaces.Length == nsCount) { Namespace[] newNamespaces = new Namespace[nsCount * 2]; Array.Copy(namespaces, newNamespaces, nsCount); namespaces = newNamespaces; } Namespace nameSpace = namespaces[nsCount]; if (nameSpace == null) { nameSpace = new Namespace(bufferReader); namespaces[nsCount] = nameSpace; } nameSpace.Clear(); nameSpace.Depth = depth; nsCount++; return nameSpace; } public Namespace LookupNamespace(PrefixHandleType prefix) { return shortPrefixUri[(int)prefix]; } public Namespace LookupNamespace(PrefixHandle prefix) { PrefixHandleType shortPrefix; if (prefix.TryGetShortPrefix(out shortPrefix)) return LookupNamespace(shortPrefix); for (int i = nsCount - 1; i >= 0; i--) { Namespace nameSpace = namespaces[i]; if (nameSpace.Prefix == prefix) return nameSpace; } if (prefix.IsXml) return XmlNamespace; return null; } public Namespace LookupNamespace(string prefix) { PrefixHandleType shortPrefix; if (TryGetShortPrefix(prefix, out shortPrefix)) return LookupNamespace(shortPrefix); for (int i = nsCount - 1; i >= 0; i--) { Namespace nameSpace = namespaces[i]; if (nameSpace.Prefix == prefix) return nameSpace; } if (prefix == "xml") return XmlNamespace; return null; } bool TryGetShortPrefix(string s, out PrefixHandleType shortPrefix) { int length = s.Length; if (length == 0) { shortPrefix = PrefixHandleType.Empty; return true; } if (length == 1) { char ch = s[0]; if (ch >= 'a' && ch <= 'z') { shortPrefix = PrefixHandle.GetAlphaPrefix(ch - 'a'); return true; } } shortPrefix = PrefixHandleType.Empty; return false; } class XmlAttribute { XmlSpace space; string lang; int depth; public XmlAttribute() { } public int Depth { get { return depth; } set { depth = value; } } public string XmlLang { get { return lang; } set { lang = value; } } public XmlSpace XmlSpace { get { return space; } set { space = value; } } } } protected class Namespace { PrefixHandle prefix; StringHandle uri; int depth; Namespace outerUri; string uriString; public Namespace(XmlBufferReader bufferReader) { this.prefix = new PrefixHandle(bufferReader); this.uri = new StringHandle(bufferReader); this.outerUri = null; this.uriString = null; } public void Clear() { this.uriString = null; } public int Depth { get { return depth; } set { depth = value; } } public PrefixHandle Prefix { get { return prefix; } } public bool IsUri(string s) { DiagnosticUtility.DebugAssert(s != null, ""); if (object.ReferenceEquals(s, uriString)) return true; if (uri == s) { uriString = s; return true; } return false; } public bool IsUri(XmlDictionaryString s) { if (object.ReferenceEquals(s.Value, uriString)) return true; if (uri == s) { uriString = s.Value; return true; } return false; } public StringHandle Uri { get { return uri; } } public Namespace OuterUri { get { return outerUri; } set { outerUri = value; } } } class QuotaNameTable : XmlNameTable { XmlDictionaryReader reader; XmlNameTable nameTable; int maxCharCount; int charCount; public QuotaNameTable(XmlDictionaryReader reader, int maxCharCount) { this.reader = reader; this.nameTable = new NameTable(); this.maxCharCount = maxCharCount; this.charCount = 0; } public override string Get(char[] chars, int offset, int count) { return nameTable.Get(chars, offset, count); } public override string Get(string value) { return nameTable.Get(value); } void Add(int charCount) { if (charCount > this.maxCharCount - this.charCount) XmlExceptionHelper.ThrowMaxNameTableCharCountExceeded(reader, maxCharCount); this.charCount += charCount; } public override string Add(char[] chars, int offset, int count) { string s = nameTable.Get(chars, offset, count); if (s != null) return s; Add(count); return nameTable.Add(chars, offset, count); } public override string Add(string value) { string s = nameTable.Get(value); if (s != null) return s; Add(value.Length); return nameTable.Add(value); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProtocolViolationException.cs
- OLEDB_Enum.cs
- MulticastDelegate.cs
- AspNetCacheProfileAttribute.cs
- AsyncContentLoadedEventArgs.cs
- IIS7WorkerRequest.cs
- RuleRefElement.cs
- ZipIOCentralDirectoryFileHeader.cs
- ToggleButton.cs
- XmlSchemaSimpleContent.cs
- ScalarType.cs
- SQLCharsStorage.cs
- PointCollection.cs
- PersonalizablePropertyEntry.cs
- ActivityPreviewDesigner.cs
- ArgIterator.cs
- CheckBoxRenderer.cs
- ApplicationProxyInternal.cs
- HtmlInputReset.cs
- EmptyTextWriter.cs
- LinqDataSourceContextEventArgs.cs
- Rijndael.cs
- UnmanagedMemoryStream.cs
- XmlSchemaImporter.cs
- PiiTraceSource.cs
- SoapCommonClasses.cs
- WebRequestModuleElement.cs
- IxmlLineInfo.cs
- XamlToRtfWriter.cs
- PageStatePersister.cs
- FormViewRow.cs
- HttpResponseHeader.cs
- CookielessHelper.cs
- ValidatedMobileControlConverter.cs
- OrderPreservingMergeHelper.cs
- DbProviderSpecificTypePropertyAttribute.cs
- XsltContext.cs
- TraceFilter.cs
- figurelengthconverter.cs
- HtmlTextViewAdapter.cs
- diagnosticsswitches.cs
- CommonProperties.cs
- RawStylusInputCustomDataList.cs
- OracleParameterBinding.cs
- CodeCastExpression.cs
- ManagedWndProcTracker.cs
- NativeObjectSecurity.cs
- Point3DConverter.cs
- BindingSource.cs
- ConnectionPointGlyph.cs
- MemberListBinding.cs
- AppSettingsExpressionBuilder.cs
- WebBrowserContainer.cs
- ValidationError.cs
- Decorator.cs
- RegexParser.cs
- WindowsListViewScroll.cs
- StrongTypingException.cs
- Ref.cs
- NetworkInterface.cs
- TrackingServices.cs
- CryptoStream.cs
- SvcMapFileSerializer.cs
- DetailsViewUpdateEventArgs.cs
- XmlHierarchyData.cs
- PlainXmlSerializer.cs
- BaseHashHelper.cs
- DateTimeAutomationPeer.cs
- RuleCache.cs
- WebPartMinimizeVerb.cs
- DataTableMappingCollection.cs
- MemberMaps.cs
- WebEventTraceProvider.cs
- SafeCryptContextHandle.cs
- PasswordDeriveBytes.cs
- PropertyInfoSet.cs
- JsonReaderWriterFactory.cs
- Ref.cs
- DelayedRegex.cs
- MessagePropertyVariants.cs
- ColumnMapVisitor.cs
- MobileUserControl.cs
- StylusPointDescription.cs
- MasterPageCodeDomTreeGenerator.cs
- RefreshEventArgs.cs
- TemplateBindingExtensionConverter.cs
- PackageFilter.cs
- ScriptReferenceEventArgs.cs
- FlowDocumentScrollViewer.cs
- ReverseInheritProperty.cs
- CannotUnloadAppDomainException.cs
- CodeConditionStatement.cs
- ToolBar.cs
- GatewayDefinition.cs
- MsmqAppDomainProtocolHandler.cs
- FrameworkTemplate.cs
- LassoSelectionBehavior.cs
- SslStreamSecurityUpgradeProvider.cs
- TextDecorationLocationValidation.cs
- XmlUrlEditor.cs