File: System\Security\Cryptography\Xml\CanonicalizationDispatcher.cs
Web Access
Project: src\src\libraries\System.Security.Cryptography.Xml\src\System.Security.Cryptography.Xml.csproj (System.Security.Cryptography.Xml)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Text;
using System.Xml;
 
namespace System.Security.Cryptography.Xml
{
    // the central dispatcher for canonicalization writes. not all node classes
    // implement ICanonicalizableNode; so a manual dispatch is sometimes necessary.
    internal static class CanonicalizationDispatcher
    {
        [ThreadStatic]
        private static int t_depth;
 
        public static void Write(XmlNode node, StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc)
        {
            int maxDepth = LocalAppContextSwitches.DangerousMaxRecursionDepth;
            if (maxDepth > 0 && t_depth > maxDepth)
            {
                throw new CryptographicException(SR.Cryptography_Xml_MaxDepthExceeded);
            }
 
            t_depth++;
            try
            {
                if (node is ICanonicalizableNode canonicalizableNode)
                {
                    canonicalizableNode.Write(strBuilder, docPos, anc);
                }
                else
                {
                    WriteGenericNode(node, strBuilder, docPos, anc);
                }
            }
            finally
            {
                t_depth--;
            }
        }
 
        public static void WriteGenericNode(XmlNode node, StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc)
        {
            ArgumentNullException.ThrowIfNull(node);
 
            XmlNodeList childNodes = node.ChildNodes;
            foreach (XmlNode childNode in childNodes)
            {
                Write(childNode, strBuilder, docPos, anc);
            }
        }
 
        public static void WriteHash(XmlNode node, HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc)
        {
            int maxDepth = LocalAppContextSwitches.DangerousMaxRecursionDepth;
            if (maxDepth > 0 && t_depth > maxDepth)
            {
                throw new CryptographicException(SR.Cryptography_Xml_MaxDepthExceeded);
            }
 
            t_depth++;
            try
            {
                if (node is ICanonicalizableNode canonicalizableNode)
                {
                    canonicalizableNode.WriteHash(hash, docPos, anc);
                }
                else
                {
                    WriteHashGenericNode(node, hash, docPos, anc);
                }
            }
            finally
            {
                t_depth--;
            }
        }
 
        public static void WriteHashGenericNode(XmlNode node, HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc)
        {
            ArgumentNullException.ThrowIfNull(node);
 
            XmlNodeList childNodes = node.ChildNodes;
            foreach (XmlNode childNode in childNodes)
            {
                WriteHash(childNode, hash, docPos, anc);
            }
        }
    }
}