You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			146 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="WhitespaceRuleReader.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| // <owner current="true" primary="true">Microsoft</owner>
 | |
| //------------------------------------------------------------------------------
 | |
| using System;
 | |
| using System.IO;
 | |
| using System.Xml;
 | |
| using System.Xml.Schema;
 | |
| using System.Diagnostics;
 | |
| using MS.Internal.Xml;
 | |
| 
 | |
| namespace System.Xml.Xsl.Runtime {
 | |
| 
 | |
|     /// <summary>
 | |
|     /// </summary>
 | |
|     internal class WhitespaceRuleReader : XmlWrappingReader {
 | |
|         private WhitespaceRuleLookup wsRules;
 | |
|         private BitStack stkStrip;
 | |
|         private bool shouldStrip, preserveAdjacent;
 | |
|         private string val;
 | |
|         private XmlCharType xmlCharType = XmlCharType.Instance;
 | |
| 
 | |
|         static public XmlReader CreateReader(XmlReader baseReader, WhitespaceRuleLookup wsRules) {
 | |
|             if (wsRules == null) {
 | |
|                 return baseReader;    // There is no rules to process
 | |
|             }
 | |
|             XmlReaderSettings readerSettings = baseReader.Settings;
 | |
|             if (readerSettings != null) {
 | |
|                 if (readerSettings.IgnoreWhitespace) {
 | |
|                     return baseReader;        // V2 XmlReader that strips all WS
 | |
|                 }
 | |
|             } else {
 | |
|                 XmlTextReader txtReader = baseReader as XmlTextReader;
 | |
|                 if (txtReader != null && txtReader.WhitespaceHandling == WhitespaceHandling.None) {
 | |
|                     return baseReader;        // V1 XmlTextReader that strips all WS
 | |
|                 }
 | |
|                 XmlTextReaderImpl txtReaderImpl = baseReader as XmlTextReaderImpl;
 | |
|                 if (txtReaderImpl != null && txtReaderImpl.WhitespaceHandling == WhitespaceHandling.None) {
 | |
|                     return baseReader;        // XmlTextReaderImpl that strips all WS
 | |
|                 }
 | |
|             }
 | |
|             return new WhitespaceRuleReader(baseReader, wsRules);
 | |
|         }
 | |
| 
 | |
|         private WhitespaceRuleReader(XmlReader baseReader, WhitespaceRuleLookup wsRules) : base(baseReader) {
 | |
|             Debug.Assert(wsRules != null);
 | |
| 
 | |
|             this.val = null;
 | |
|             this.stkStrip = new BitStack();
 | |
|             this.shouldStrip = false;
 | |
|             this.preserveAdjacent = false;
 | |
| 
 | |
|             this.wsRules = wsRules;
 | |
|             this.wsRules.Atomize(baseReader.NameTable);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Override Value in order to possibly prepend extra whitespace.
 | |
|         /// </summary>
 | |
|         public override string Value {
 | |
|             get { return (this.val == null) ? base.Value : this.val; }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Override Read in order to search for strippable whitespace, to concatenate adjacent text nodes, and to
 | |
|         /// resolve entities.
 | |
|         /// </summary>
 | |
|         public override bool Read() {
 | |
|             XmlCharType xmlCharType = XmlCharType.Instance;
 | |
|             string ws = null;
 | |
| 
 | |
|             // Clear text value
 | |
|             this.val = null;
 | |
| 
 | |
|             while (base.Read()) {
 | |
|                 switch (base.NodeType) {
 | |
|                 case XmlNodeType.Element:
 | |
|                     // Push boolean indicating whether whitespace children of this element should be stripped
 | |
|                     if (!base.IsEmptyElement) {
 | |
|                         this.stkStrip.PushBit(this.shouldStrip);
 | |
| 
 | |
|                         // Strip if rules say we should and we're not within the scope of xml:space="preserve"
 | |
|                         this.shouldStrip = wsRules.ShouldStripSpace(base.LocalName, base.NamespaceURI) && (base.XmlSpace != XmlSpace.Preserve);
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case XmlNodeType.EndElement:
 | |
|                     // Restore parent shouldStrip setting
 | |
|                     this.shouldStrip = this.stkStrip.PopBit();
 | |
|                     break;
 | |
| 
 | |
|                 case XmlNodeType.Text:
 | |
|                 case XmlNodeType.CDATA:
 | |
|                     // If preserving adjacent text, don't perform any further checks
 | |
|                     if (this.preserveAdjacent)
 | |
|                         return true;
 | |
| 
 | |
|                     if (this.shouldStrip) {
 | |
|                         // Reader may report whitespace as Text or CDATA
 | |
|                         if (xmlCharType.IsOnlyWhitespace(base.Value))
 | |
|                             goto case XmlNodeType.Whitespace;
 | |
| 
 | |
|                         // If whitespace was cached, then prepend it to text or CDATA value
 | |
|                         if (ws != null)
 | |
|                             this.val = string.Concat(ws, base.Value);
 | |
| 
 | |
|                         // Preserve adjacent whitespace
 | |
|                         this.preserveAdjacent = true;
 | |
|                         return true;
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case XmlNodeType.Whitespace:
 | |
|                 case XmlNodeType.SignificantWhitespace:
 | |
|                     // If preserving adjacent text, don't perform any further checks
 | |
|                     if (this.preserveAdjacent)
 | |
|                         return true;
 | |
| 
 | |
|                     if (this.shouldStrip) {
 | |
|                         // Save whitespace until it can be determined whether it will be stripped
 | |
|                         if (ws == null)
 | |
|                             ws = base.Value;
 | |
|                         else
 | |
|                             ws = string.Concat(ws, base.Value);
 | |
| 
 | |
|                         // Read next event
 | |
|                         continue;
 | |
|                     }
 | |
|                     break;
 | |
|                 case XmlNodeType.EndEntity:
 | |
|                     // Read next event
 | |
|                     continue;
 | |
|                 }
 | |
| 
 | |
|             // No longer preserve adjacent space
 | |
|                 this.preserveAdjacent = false;
 | |
|                 return true;
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
| }
 |