The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.XsltOld \ ProcessingInstructionAction

  1. //------------------------------------------------------------------------------
  2. // <copyright file="ProcessingInstructionAction.cs" company="Microsoft">
  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. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Xml.Xsl.XsltOld
  16. {
  17.     using Res = System.Xml.Utils.Res;
  18.     using System;
  19.     using System.Diagnostics;
  20.     using System.Xml;
  21.     using System.Xml.XPath;
  22.    
  23.     internal class ProcessingInstructionAction : ContainerAction
  24.     {
  25.         private const int NameEvaluated = 2;
  26.         private const int NameReady = 3;
  27.        
  28.         private Avt nameAvt;
  29.         // Compile time precalculated AVT
  30.         private string name;
  31.        
  32.         private const char CharX = 'X';
  33.         private const char Charx = 'x';
  34.         private const char CharM = 'M';
  35.         private const char Charm = 'm';
  36.         private const char CharL = 'L';
  37.         private const char Charl = 'l';
  38.        
  39.         internal ProcessingInstructionAction()
  40.         {
  41.         }
  42.        
  43.         internal override void Compile(Compiler compiler)
  44.         {
  45.             CompileAttributes(compiler);
  46.             CheckRequiredAttribute(compiler, this.nameAvt, Keywords.s_Name);
  47.            
  48.             if (this.nameAvt.IsConstant) {
  49.                 this.name = this.nameAvt.Evaluate(null, null);
  50.                 this.nameAvt = null;
  51.                 if (!IsProcessingInstructionName(this.name)) {
  52.                     // For Now: set to null to ignore action late;
  53.                     this.name = null;
  54.                 }
  55.             }
  56.            
  57.             if (compiler.Recurse()) {
  58.                 CompileTemplate(compiler);
  59.                 compiler.ToParent();
  60.             }
  61.         }
  62.        
  63.         internal override bool CompileAttribute(Compiler compiler)
  64.         {
  65.             string name = compiler.Input.LocalName;
  66.             string value = compiler.Input.Value;
  67.             if (Keywords.Equals(name, compiler.Atoms.Name)) {
  68.                 this.nameAvt = Avt.CompileAvt(compiler, value);
  69.             }
  70.             else {
  71.                 return false;
  72.             }
  73.            
  74.             return true;
  75.         }
  76.        
  77.         internal override void Execute(Processor processor, ActionFrame frame)
  78.         {
  79.             Debug.Assert(processor != null && frame != null);
  80.            
  81.             switch (frame.State) {
  82.                 case Initialized:
  83.                     if (this.nameAvt == null) {
  84.                         frame.StoredOutput = this.name;
  85.                         if (this.name == null) {
  86.                             // name was static but was bad;
  87.                             frame.Finished();
  88.                             break;
  89.                         }
  90.                     }
  91.                     else {
  92.                         frame.StoredOutput = this.nameAvt.Evaluate(processor, frame);
  93.                         if (!IsProcessingInstructionName(frame.StoredOutput)) {
  94.                             frame.Finished();
  95.                             break;
  96.                         }
  97.                     }
  98.                     goto case NameReady;
  99.                     break;
  100.                 case NameReady:
  101.                    
  102.                     Debug.Assert(frame.StoredOutput != null);
  103.                     if (processor.BeginEvent(XPathNodeType.ProcessingInstruction, string.Empty, frame.StoredOutput, string.Empty, false) == false) {
  104.                         // Come back later
  105.                         frame.State = NameReady;
  106.                         break;
  107.                     }
  108.                     processor.PushActionFrame(frame);
  109.                     frame.State = ProcessingChildren;
  110.                     break;
  111.                 case ProcessingChildren:
  112.                     // Allow children to run
  113.                     if (processor.EndEvent(XPathNodeType.ProcessingInstruction) == false) {
  114.                         frame.State = ProcessingChildren;
  115.                         break;
  116.                     }
  117.                     frame.Finished();
  118.                     break;
  119.                 default:
  120.                     Debug.Fail("Invalid ElementAction execution state");
  121.                     frame.Finished();
  122.                     break;
  123.             }
  124.         }
  125.        
  126.        
  127.         static internal bool IsProcessingInstructionName(string name)
  128.         {
  129.             if (name == null) {
  130.                 return false;
  131.             }
  132.            
  133.             int nameLength = name.Length;
  134.             int position = 0;
  135.             XmlCharType xmlCharType = XmlCharType.Instance;
  136.            
  137.             while (position < nameLength && xmlCharType.IsWhiteSpace(name[position])) {
  138.                 position++;
  139.             }
  140.            
  141.             if (position >= nameLength) {
  142.                 return false;
  143.             }
  144.            
  145.             if (position < nameLength && !xmlCharType.IsStartNCNameChar(name[position])) {
  146.                 return false;
  147.             }
  148.            
  149.             while (position < nameLength && xmlCharType.IsNCNameChar(name[position])) {
  150.                 position++;
  151.             }
  152.            
  153.             while (position < nameLength && xmlCharType.IsWhiteSpace(name[position])) {
  154.                 position++;
  155.             }
  156.            
  157.             if (position < nameLength) {
  158.                 return false;
  159.             }
  160.            
  161.             if (nameLength == 3 && (name[0] == CharX || name[0] == Charx) && (name[1] == CharM || name[1] == Charm) && (name[2] == CharL || name[2] == Charl)) {
  162.                 return false;
  163.             }
  164.            
  165.             return true;
  166.         }
  167.     }
  168. }

Developer Fusion