The Labs \ Source Viewer \ SSCLI \ System.Security \ SecurityDocument

  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: SecurityDocument.cs
  18. //
  19. // PURPOSE: Represent an XML document
  20. //
  21. //
  22. //---------------------------------------------------------------------------
  23. namespace System.Security
  24. {
  25.     using System;
  26.     using System.Collections;
  27.     using System.Security.Util;
  28.     using System.Text;
  29.     using System.Globalization;
  30.     using System.IO;
  31.     using StringMaker = System.Security.Util.Tokenizer.StringMaker;
  32.    
  33.     [Serializable()]
  34.     internal sealed class SecurityDocumentElement : ISecurityElementFactory
  35.     {
  36.         private int m_position;
  37.         private SecurityDocument m_document;
  38.        
  39.         internal SecurityDocumentElement(SecurityDocument document, int position)
  40.         {
  41.             m_document = document;
  42.             m_position = position;
  43.         }
  44.        
  45.         SecurityElement ISecurityElementFactory.CreateSecurityElement()
  46.         {
  47.             return m_document.GetElement(m_position, true);
  48.         }
  49.        
  50.         object ISecurityElementFactory.Copy()
  51.         {
  52.             return new SecurityDocumentElement(m_document, m_position);
  53.         }
  54.        
  55.         string ISecurityElementFactory.GetTag()
  56.         {
  57.             return m_document.GetTagForElement(m_position);
  58.         }
  59.        
  60.         string ISecurityElementFactory.Attribute(string attributeName)
  61.         {
  62.             return m_document.GetAttributeForElement(m_position, attributeName);
  63.         }
  64.        
  65.     }
  66.    
  67.    
  68.     [Serializable()]
  69.     internal sealed class SecurityDocument
  70.     {
  71.         internal byte[] m_data;
  72.        
  73.         internal const byte c_element = 1;
  74.         internal const byte c_attribute = 2;
  75.         internal const byte c_text = 3;
  76.         internal const byte c_children = 4;
  77.         internal const int c_growthSize = 32;
  78.        
  79.         public SecurityDocument(int numData)
  80.         {
  81.             m_data = new byte[numData];
  82.         }
  83.        
  84.         public SecurityDocument(byte[] data)
  85.         {
  86.             this.m_data = data;
  87.         }
  88.        
  89.         public SecurityDocument(SecurityElement elRoot)
  90.         {
  91.             m_data = new byte[c_growthSize];
  92.            
  93.             int position = 0;
  94.             ConvertElement(elRoot, ref position);
  95.         }
  96.        
  97.         public void GuaranteeSize(int size)
  98.         {
  99.             if (m_data.Length < size) {
  100.                 byte[] m_newData = new byte[((size / c_growthSize) + 1) * c_growthSize];
  101.                 Array.Copy(m_data, 0, m_newData, 0, m_data.Length);
  102.                 m_data = m_newData;
  103.             }
  104.         }
  105.        
  106.         public void AddString(string str, ref int position)
  107.         {
  108.            
  109.             GuaranteeSize(position + str.Length * 2 + 2);
  110.            
  111.             for (int i = 0; i < str.Length; ++i) {
  112.                 m_data[position + (2 * i)] = (byte)(str[i] >> 8);
  113.                 m_data[position + (2 * i) + 1] = (byte)(str[i] & 255);
  114.             }
  115.             m_data[position + str.Length * 2] = 0;
  116.             m_data[position + str.Length * 2 + 1] = 0;
  117.            
  118.             position += str.Length * 2 + 2;
  119.         }
  120.        
  121.         public void AppendString(string str, ref int position)
  122.         {
  123.             if (position <= 1 || m_data[position - 1] != 0 || m_data[position - 2] != 0)
  124.                 throw new XmlSyntaxException();
  125.            
  126.             position -= 2;
  127.            
  128.             AddString(str, ref position);
  129.         }
  130.        
  131.         public static int EncodedStringSize(string str)
  132.         {
  133.             return str.Length * 2 + 2;
  134.         }
  135.        
  136.         public string GetString(ref int position)
  137.         {
  138.             return GetString(ref position, true);
  139.         }
  140.        
  141.         public string GetString(ref int position, bool bCreate)
  142.         {
  143.             int stringEnd;
  144.             bool bFoundEnd = false;
  145.             for (stringEnd = position; stringEnd < m_data.Length - 1; stringEnd += 2) {
  146.                 if (m_data[stringEnd] == 0 && m_data[stringEnd + 1] == 0) {
  147.                     bFoundEnd = true;
  148.                     break;
  149.                 }
  150.             }
  151.            
  152.             BCLDebug.Assert(bFoundEnd, "Malformed string in parse data");
  153.            
  154.             StringMaker m = System.SharedStatics.GetSharedStringMaker();
  155.            
  156.             try {
  157.                
  158.                 if (bCreate) {
  159.                     m._outStringBuilder = null;
  160.                     m._outIndex = 0;
  161.                    
  162.                     for (int i = position; i < stringEnd; i += 2) {
  163.                         char c = (char)(m_data[i] << 8 | m_data[i + 1]);
  164.                        
  165.                         // add character to the string
  166.                         if (m._outIndex < StringMaker.outMaxSize) {
  167.                             // easy case
  168.                             m._outChars[m._outIndex++] = c;
  169.                         }
  170.                         else {
  171.                             if (m._outStringBuilder == null) {
  172.                                 // OK, first check if we have to init the StringBuilder
  173.                                 m._outStringBuilder = new StringBuilder();
  174.                             }
  175.                            
  176.                             // OK, copy from _outChars to _outStringBuilder
  177.                             m._outStringBuilder.Append(m._outChars, 0, StringMaker.outMaxSize);
  178.                            
  179.                             // reset _outChars pointer
  180.                             m._outChars[0] = c;
  181.                             m._outIndex = 1;
  182.                         }
  183.                     }
  184.                 }
  185.                
  186.                 position = stringEnd + 2;
  187.                
  188.                 if (bCreate)
  189.                     return m.MakeString();
  190.                 else
  191.                     return null;
  192.             }
  193.             finally {
  194.                 System.SharedStatics.ReleaseSharedStringMaker(ref m);
  195.             }
  196.         }
  197.        
  198.        
  199.         public void AddToken(byte b, ref int position)
  200.         {
  201.             GuaranteeSize(position + 1);
  202.             m_data[position++] = b;
  203.         }
  204.        
  205.         public void ConvertElement(SecurityElement elCurrent, ref int position)
  206.         {
  207.             AddToken(c_element, ref position);
  208.             AddString(elCurrent.m_strTag, ref position);
  209.            
  210.             if (elCurrent.m_lAttributes != null) {
  211.                 for (int i = 0; i < elCurrent.m_lAttributes.Count; i += 2) {
  212.                     AddToken(c_attribute, ref position);
  213.                     AddString((string)elCurrent.m_lAttributes[i], ref position);
  214.                     AddString((string)elCurrent.m_lAttributes[i + 1], ref position);
  215.                 }
  216.             }
  217.            
  218.             if (elCurrent.m_strText != null) {
  219.                 AddToken(c_text, ref position);
  220.                 AddString(elCurrent.m_strText, ref position);
  221.             }
  222.            
  223.             if (elCurrent.InternalChildren != null) {
  224.                 for (int i = 0; i < elCurrent.InternalChildren.Count; ++i) {
  225.                     ConvertElement((SecurityElement)elCurrent.Children[i], ref position);
  226.                 }
  227.             }
  228.             AddToken(c_children, ref position);
  229.         }
  230.        
  231.         public SecurityElement GetRootElement()
  232.         {
  233.             return GetElement(0, true);
  234.         }
  235.        
  236.         public SecurityElement GetElement(int position, bool bCreate)
  237.         {
  238.             SecurityElement elRoot = InternalGetElement(ref position, bCreate);
  239.             return elRoot;
  240.         }
  241.        
  242.         internal SecurityElement InternalGetElement(ref int position, bool bCreate)
  243.         {
  244.             if (m_data.Length <= position)
  245.                 throw new XmlSyntaxException();
  246.            
  247.             if (m_data[position++] != c_element)
  248.                 throw new XmlSyntaxException();
  249.            
  250.             SecurityElement elCurrent = null;
  251.             string strTag = GetString(ref position, bCreate);
  252.             if (bCreate)
  253.                 elCurrent = new SecurityElement(strTag);
  254.            
  255.             while (m_data[position] == c_attribute) {
  256.                 position++;
  257.                 string strName = GetString(ref position, bCreate);
  258.                 string strValue = GetString(ref position, bCreate);
  259.                 if (bCreate)
  260.                     elCurrent.AddAttribute(strName, strValue);
  261.             }
  262.            
  263.             if (m_data[position] == c_text) {
  264.                 position++;
  265.                 string strText = GetString(ref position, bCreate);
  266.                 if (bCreate)
  267.                     elCurrent.m_strText = strText;
  268.             }
  269.            
  270.             while (m_data[position] != c_children) {
  271.                 SecurityElement elChild = InternalGetElement(ref position, bCreate);
  272.                 if (bCreate)
  273.                     elCurrent.AddChild(elChild);
  274.             }
  275.             position++;
  276.            
  277.             return elCurrent;
  278.         }
  279.        
  280.         public string GetTagForElement(int position)
  281.         {
  282.             if (m_data.Length <= position)
  283.                 throw new XmlSyntaxException();
  284.            
  285.             if (m_data[position++] != c_element)
  286.                 throw new XmlSyntaxException();
  287.            
  288.             string strTag = GetString(ref position);
  289.             return strTag;
  290.         }
  291.        
  292.         public ArrayList GetChildrenPositionForElement(int position)
  293.         {
  294.             if (m_data.Length <= position)
  295.                 throw new XmlSyntaxException();
  296.            
  297.             if (m_data[position++] != c_element)
  298.                 throw new XmlSyntaxException();
  299.            
  300.             ArrayList children = new ArrayList();
  301.            
  302.             // This is to move past the tag string
  303.             GetString(ref position);
  304.            
  305.             while (m_data[position] == c_attribute) {
  306.                 position++;
  307.                 // Read name and value, then throw them away
  308.                 GetString(ref position, false);
  309.                 GetString(ref position, false);
  310.             }
  311.            
  312.             if (m_data[position] == c_text) {
  313.                 position++;
  314.                 // Read text, then throw it away.
  315.                 GetString(ref position, false);
  316.             }
  317.            
  318.             while (m_data[position] != c_children) {
  319.                 children.Add(position);
  320.                 InternalGetElement(ref position, false);
  321.             }
  322.             position++;
  323.            
  324.             return children;
  325.         }
  326.        
  327.         public string GetAttributeForElement(int position, string attributeName)
  328.         {
  329.             if (m_data.Length <= position)
  330.                 throw new XmlSyntaxException();
  331.            
  332.             if (m_data[position++] != c_element)
  333.                 throw new XmlSyntaxException();
  334.            
  335.             string strRetValue = null;
  336.             // This is to move past the tag string.
  337.             GetString(ref position, false);
  338.            
  339.            
  340.             while (m_data[position] == c_attribute) {
  341.                 position++;
  342.                 string strName = GetString(ref position);
  343.                 string strValue = GetString(ref position);
  344.                
  345.                 if (String.Equals(strName, attributeName)) {
  346.                     strRetValue = strValue;
  347.                     break;
  348.                 }
  349.             }
  350.            
  351.            
  352.             return strRetValue;
  353.         }
  354.     }
  355. }

Developer Fusion