The Labs \ Source Viewer \ SSCLI \ System \ ConfigNodeType

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** Class: CfgParser
  18. **
  19. **
  20. ** Purpose: XMLParser and Tree builder internal to BCL
  21. **
  22. **
  23. ===========================================================*/
  24. //
  25. // These are managed definitions of interfaces used in the shim for XML Parsing
  26. // If you make any change please make a correspoding change in \src\dlls\shim\managedhelper.h
  27. //
  28. //
  29. //
  30. namespace System
  31. {
  32.     using System.Runtime.InteropServices;
  33.     using System.Collections;
  34.     using System.Runtime.CompilerServices;
  35.     using System.Security.Permissions;
  36.     using System.Security;
  37.     using System.Globalization;
  38.     using System.IO;
  39.     using System.Runtime.Versioning;
  40.    
  41.     [Serializable()]
  42.     internal enum ConfigEvents
  43.     {
  44.         StartDocument = 0,
  45.         StartDTD = StartDocument + 1,
  46.         EndDTD = StartDTD + 1,
  47.         StartDTDSubset = EndDTD + 1,
  48.         EndDTDSubset = StartDTDSubset + 1,
  49.         EndProlog = EndDTDSubset + 1,
  50.         StartEntity = EndProlog + 1,
  51.         EndEntity = StartEntity + 1,
  52.         EndDocument = EndEntity + 1,
  53.         DataAvailable = EndDocument + 1,
  54.         LastEvent = DataAvailable
  55.     }
  56.    
  57.     [Serializable()]
  58.     internal enum ConfigNodeType
  59.     {
  60.         Element = 1,
  61.         Attribute = Element + 1,
  62.         Pi = Attribute + 1,
  63.         XmlDecl = Pi + 1,
  64.         DocType = XmlDecl + 1,
  65.         DTDAttribute = DocType + 1,
  66.         EntityDecl = DTDAttribute + 1,
  67.         ElementDecl = EntityDecl + 1,
  68.         AttlistDecl = ElementDecl + 1,
  69.         Notation = AttlistDecl + 1,
  70.         Group = Notation + 1,
  71.         IncludeSect = Group + 1,
  72.         PCData = IncludeSect + 1,
  73.         CData = PCData + 1,
  74.         IgnoreSect = CData + 1,
  75.         Comment = IgnoreSect + 1,
  76.         EntityRef = Comment + 1,
  77.         Whitespace = EntityRef + 1,
  78.         Name = Whitespace + 1,
  79.         NMToken = Name + 1,
  80.         String = NMToken + 1,
  81.         Peref = String + 1,
  82.         Model = Peref + 1,
  83.         ATTDef = Model + 1,
  84.         ATTType = ATTDef + 1,
  85.         ATTPresence = ATTType + 1,
  86.         DTDSubset = ATTPresence + 1,
  87.         LastNodeType = DTDSubset + 1
  88.     }
  89.    
  90.     [Serializable()]
  91.     internal enum ConfigNodeSubType
  92.     {
  93.         Version = (int)ConfigNodeType.LastNodeType,
  94.         Encoding = Version + 1,
  95.         Standalone = Encoding + 1,
  96.         NS = Standalone + 1,
  97.         XMLSpace = NS + 1,
  98.         XMLLang = XMLSpace + 1,
  99.         System = XMLLang + 1,
  100.         Public = System + 1,
  101.         NData = Public + 1,
  102.         AtCData = NData + 1,
  103.         AtId = AtCData + 1,
  104.         AtIdref = AtId + 1,
  105.         AtIdrefs = AtIdref + 1,
  106.         AtEntity = AtIdrefs + 1,
  107.         AtEntities = AtEntity + 1,
  108.         AtNmToken = AtEntities + 1,
  109.         AtNmTokens = AtNmToken + 1,
  110.         AtNotation = AtNmTokens + 1,
  111.         AtRequired = AtNotation + 1,
  112.         AtImplied = AtRequired + 1,
  113.         AtFixed = AtImplied + 1,
  114.         PentityDecl = AtFixed + 1,
  115.         Empty = PentityDecl + 1,
  116.         Any = Empty + 1,
  117.         Mixed = Any + 1,
  118.         Sequence = Mixed + 1,
  119.         Choice = Sequence + 1,
  120.         Star = Choice + 1,
  121.         Plus = Star + 1,
  122.         Questionmark = Plus + 1,
  123.         LastSubNodeType = Questionmark + 1
  124.     }
  125.    
  126.     [Guid("afd0d21f-72f8-4819-99ad-3f255ee5006b"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
  127.     internal interface IConfigHandler
  128.     {
  129.        
  130.         void NotifyEvent(ConfigEvents nEvent);
  131.        
  132.         void BeginChildren(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  133. string text, int textLength, int prefixLength);
  134.        
  135.         void EndChildren(int fEmpty, int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  136. string text, int textLength, int prefixLength);
  137.        
  138.         void Error(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  139. string text, int textLength, int prefixLength);
  140.        
  141.         void CreateNode(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  142. string text, int textLength, int prefixLength);
  143.        
  144.         void CreateAttribute(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  145. string text, int textLength, int prefixLength);
  146.     }
  147.    
  148.     static internal class ConfigServer
  149.     {
  150.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  151.         static internal extern void RunParser(IConfigHandler factory, string fileName);
  152.     }
  153.    
  154.     // Class used to build a DOM like tree of parsed XML
  155.     internal class ConfigTreeParser : IConfigHandler
  156.     {
  157.         ConfigNode rootNode = null;
  158.         ConfigNode currentNode = null;
  159.         string lastProcessed = null;
  160.         string fileName = null;
  161.         int attributeEntry;
  162.         string key = null;
  163.         string[] treeRootPath = null;
  164.         // element to start tree
  165.         bool parsing = false;
  166.         int depth = 0;
  167.         int pathDepth = 0;
  168.         int searchDepth = 0;
  169.         bool bNoSearchPath = false;
  170.        
  171.         // NOTE: This parser takes a path eg. /configuration/system.runtime.remoting
  172.         // and will return a node which matches this.
  173.         [ResourceExposure(ResourceScope.Machine)]
  174.         [ResourceConsumption(ResourceScope.Machine)]
  175.         internal ConfigNode Parse(string fileName, string configPath)
  176.         {
  177.             return Parse(fileName, configPath, false);
  178.         }
  179.        
  180.         [ResourceExposure(ResourceScope.Machine)]
  181.         [ResourceConsumption(ResourceScope.Machine)]
  182.         internal ConfigNode Parse(string fileName, string configPath, bool skipSecurityStuff)
  183.         {
  184.             if (fileName == null)
  185.                 throw new ArgumentNullException("fileName");
  186.             this.fileName = fileName;
  187.             if (configPath[0] == '/') {
  188.                 treeRootPath = configPath.Substring(1).Split('/');
  189.                 pathDepth = treeRootPath.Length - 1;
  190.                 bNoSearchPath = false;
  191.             }
  192.             else {
  193.                 treeRootPath = new string[1];
  194.                 treeRootPath[0] = configPath;
  195.                 bNoSearchPath = true;
  196.             }
  197.            
  198.             if (!skipSecurityStuff) {
  199.                 (new FileIOPermission(FileIOPermissionAccess.Read, System.IO.Path.GetFullPathInternal(fileName))).Demand();
  200.             }
  201.             (new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert();
  202.            
  203.             try {
  204.                 ConfigServer.RunParser(this, fileName);
  205.             }
  206.             catch (FileNotFoundException) {
  207.                 throw;
  208.                 // Pass these through unadulterated.
  209.             }
  210.             catch (DirectoryNotFoundException) {
  211.                 throw;
  212.                 // Pass these through unadulterated.
  213.             }
  214.             catch (UnauthorizedAccessException) {
  215.                 throw;
  216.             }
  217.             catch (FileLoadException) {
  218.                 throw;
  219.             }
  220.             catch (Exception inner) {
  221.                 throw new ApplicationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("XML_Syntax_InvalidSyntaxInFile"), fileName, lastProcessed), inner);
  222.             }
  223.             catch {
  224.                 throw new ApplicationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("XML_Syntax_InvalidSyntaxInFile"), fileName, lastProcessed));
  225.             }
  226.             return rootNode;
  227.         }
  228.        
  229.         public void NotifyEvent(ConfigEvents nEvent)
  230.         {
  231.             BCLDebug.Trace("REMOTE", "NotifyEvent " + ((Enum)nEvent).ToString() + "\n");
  232.         }
  233.        
  234.         public void BeginChildren(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  235. string text, int textLength, int prefixLength)
  236.         {
  237.             //Trace("BeginChildren",size,subType,nType,terminal,text,textLength,prefixLength,0);
  238.             if (!parsing && (!bNoSearchPath && depth == (searchDepth + 1) && String.Compare(text, treeRootPath[searchDepth], StringComparison.Ordinal) == 0)) {
  239.                 searchDepth++;
  240.             }
  241.         }
  242.        
  243.         public void EndChildren(int fEmpty, int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  244. string text, int textLength, int prefixLength)
  245.         {
  246.             lastProcessed = "</" + text + ">";
  247.             if (parsing) {
  248.                 //Trace("EndChildren",size,subType,nType,terminal,text,textLength,prefixLength,fEmpty);
  249.                
  250.                 if (currentNode == rootNode) {
  251.                     // End of section of tree which is parsed
  252.                     parsing = false;
  253.                 }
  254.                
  255.                 currentNode = currentNode.Parent;
  256.             }
  257.             else if (nType == ConfigNodeType.Element) {
  258.                 if (depth == searchDepth && String.Compare(text, treeRootPath[searchDepth - 1], StringComparison.Ordinal) == 0) {
  259.                     searchDepth--;
  260.                     depth--;
  261.                 }
  262.                 else
  263.                     depth--;
  264.             }
  265.            
  266.         }
  267.        
  268.         public void Error(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  269. string text, int textLength, int prefixLength)
  270.         {
  271.             //Trace("Error",size,subType,nType,terminal,text,textLength,prefixLength,0);
  272.         }
  273.        
  274.        
  275.         public void CreateNode(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  276. string text, int textLength, int prefixLength)
  277.         {
  278.             //Trace("CreateNode",size,subType,nType,terminal,text,textLength,prefixLength,0);
  279.            
  280.             if (nType == ConfigNodeType.Element) {
  281.                 // New Node
  282.                 lastProcessed = "<" + text + ">";
  283.                 if (parsing || (bNoSearchPath && String.Compare(text, treeRootPath[0], StringComparison.OrdinalIgnoreCase) == 0) || (depth == searchDepth && searchDepth == pathDepth && String.Compare(text, treeRootPath[pathDepth], StringComparison.OrdinalIgnoreCase) == 0)) {
  284.                     parsing = true;
  285.                    
  286.                     ConfigNode parentNode = currentNode;
  287.                     currentNode = new ConfigNode(text, parentNode);
  288.                     if (rootNode == null)
  289.                         rootNode = currentNode;
  290.                     else
  291.                         parentNode.AddChild(currentNode);
  292.                 }
  293.                 else
  294.                     depth++;
  295.             }
  296.             else if (nType == ConfigNodeType.PCData) {
  297.                 // Data node
  298.                 if (currentNode != null) {
  299.                     currentNode.Value = text;
  300.                 }
  301.             }
  302.         }
  303.        
  304.         public void CreateAttribute(int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  305. string text, int textLength, int prefixLength)
  306.         {
  307.             //Trace("CreateAttribute",size,subType,nType,terminal,text,textLength,prefixLength,0);
  308.             if (parsing) {
  309.                 // if the value of the attribute is null, the parser doesn't come back, so need to store the attribute when the
  310.                 // attribute name is encountered
  311.                 if (nType == ConfigNodeType.Attribute) {
  312.                     attributeEntry = currentNode.AddAttribute(text, "");
  313.                     key = text;
  314.                 }
  315.                 else if (nType == ConfigNodeType.PCData) {
  316.                     currentNode.ReplaceAttribute(attributeEntry, key, text);
  317.                 }
  318.                 else
  319.                     throw new ApplicationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("XML_Syntax_InvalidSyntaxInFile"), fileName, lastProcessed));
  320.             }
  321.         }
  322.        
  323.         [System.Diagnostics.Conditional("_LOGGING")]
  324.         private void Trace(string name, int size, ConfigNodeSubType subType, ConfigNodeType nType, int terminal,         [MarshalAs(UnmanagedType.LPWStr)]
  325. string text, int textLength, int prefixLength, int fEmpty)
  326.         {
  327.            
  328.             BCLDebug.Trace("REMOTE", "Node " + name);
  329.             BCLDebug.Trace("REMOTE", "text " + text);
  330.             BCLDebug.Trace("REMOTE", "textLength " + textLength);
  331.             BCLDebug.Trace("REMOTE", "size " + size);
  332.             BCLDebug.Trace("REMOTE", "subType " + ((Enum)subType).ToString());
  333.             BCLDebug.Trace("REMOTE", "nType " + ((Enum)nType).ToString());
  334.             BCLDebug.Trace("REMOTE", "terminal " + terminal);
  335.             BCLDebug.Trace("REMOTE", "prefixLength " + prefixLength);
  336.             BCLDebug.Trace("REMOTE", "fEmpty " + fEmpty + "\n");
  337.            
  338.         }
  339.     }
  340.    
  341.     // Node in Tree produced by ConfigTreeParser
  342.     internal class ConfigNode
  343.     {
  344.         string m_name = null;
  345.         string m_value = null;
  346.         ConfigNode m_parent = null;
  347.         ArrayList m_children = new ArrayList(5);
  348.         ArrayList m_attributes = new ArrayList(5);
  349.        
  350.         internal ConfigNode(string name, ConfigNode parent)
  351.         {
  352.             m_name = name;
  353.             m_parent = parent;
  354.         }
  355.        
  356.         internal string Name {
  357.             get { return m_name; }
  358.         }
  359.        
  360.         internal string Value {
  361.             get { return m_value; }
  362.             set { m_value = value; }
  363.         }
  364.        
  365.         internal ConfigNode Parent {
  366.             get { return m_parent; }
  367.         }
  368.        
  369.         internal ArrayList Children {
  370.             get { return m_children; }
  371.         }
  372.        
  373.         internal ArrayList Attributes {
  374.             get { return m_attributes; }
  375.         }
  376.        
  377.         internal void AddChild(ConfigNode child)
  378.         {
  379.             child.m_parent = this;
  380.             m_children.Add(child);
  381.         }
  382.        
  383.         internal int AddAttribute(string key, string value)
  384.         {
  385.             m_attributes.Add(new DictionaryEntry(key, value));
  386.             return m_attributes.Count - 1;
  387.         }
  388.        
  389.         internal void ReplaceAttribute(int index, string key, string value)
  390.         {
  391.             m_attributes[index] = new DictionaryEntry(key, value);
  392.         }
  393.        
  394.        
  395.         [System.Diagnostics.Conditional("_LOGGING")]
  396.         internal void Trace()
  397.         {
  398.             BCLDebug.Trace("REMOTE", "************ConfigNode************");
  399.             BCLDebug.Trace("REMOTE", "Name = " + m_name);
  400.             if (m_value != null)
  401.                 BCLDebug.Trace("REMOTE", "Value = " + m_value);
  402.             if (m_parent != null)
  403.                 BCLDebug.Trace("REMOTE", "Parent = " + m_parent.Name);
  404.             for (int i = 0; i < m_attributes.Count; i++) {
  405.                 DictionaryEntry de = (DictionaryEntry)m_attributes[i];
  406.                 BCLDebug.Trace("REMOTE", "Key = " + de.Key + " Value = " + de.Value);
  407.             }
  408.            
  409.             for (int i = 0; i < m_children.Count; i++) {
  410.                 ((ConfigNode)m_children[i]).Trace();
  411.             }
  412.         }
  413.     }
  414. }

Developer Fusion