The Labs \ Source Viewer \ SSCLI \ System.Xml \ CharEntityEncoderFallback

  1. //------------------------------------------------------------------------------
  2. // <copyright file="CharEntitiesEncodingFallback.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. using System.Text;
  16. using System.Diagnostics;
  17. using System.Globalization;
  18. namespace System.Xml
  19. {
  20.    
  21.     //
  22.     // CharEntityEncoderFallback
  23.     //
  24.    
  25.     internal class CharEntityEncoderFallback : EncoderFallback
  26.     {
  27.         private CharEntityEncoderFallbackBuffer fallbackBuffer;
  28.        
  29.         private int[] textContentMarks;
  30.         private int endMarkPos;
  31.         private int curMarkPos;
  32.         private int startOffset;
  33.        
  34.         internal CharEntityEncoderFallback()
  35.         {
  36.         }
  37.        
  38.         public override EncoderFallbackBuffer CreateFallbackBuffer()
  39.         {
  40.             if (fallbackBuffer == null) {
  41.                 fallbackBuffer = new CharEntityEncoderFallbackBuffer(this);
  42.             }
  43.             return fallbackBuffer;
  44.         }
  45.        
  46.         public override int MaxCharCount {
  47.             get { return 12; }
  48.         }
  49.        
  50.         internal int StartOffset {
  51.             get { return startOffset; }
  52.             set { startOffset = value; }
  53.         }
  54.        
  55.         internal void Reset(int[] textContentMarks, int endMarkPos)
  56.         {
  57.             this.textContentMarks = textContentMarks;
  58.             this.endMarkPos = endMarkPos;
  59.             curMarkPos = 0;
  60.         }
  61.        
  62.         internal bool CanReplaceAt(int index)
  63.         {
  64.             int mPos = curMarkPos;
  65.             int charPos = startOffset + index;
  66.             while (mPos < endMarkPos && charPos >= textContentMarks[mPos + 1]) {
  67.                 mPos++;
  68.             }
  69.             curMarkPos = mPos;
  70.            
  71.             return (mPos & 1) != 0;
  72.         }
  73.     }
  74.    
  75.     //
  76.     // CharEntityFallbackBuffer
  77.     //
  78.     internal class CharEntityEncoderFallbackBuffer : EncoderFallbackBuffer
  79.     {
  80.         private CharEntityEncoderFallback parent;
  81.        
  82.         private string charEntity = string.Empty;
  83.         private int charEntityIndex = -1;
  84.        
  85.         internal CharEntityEncoderFallbackBuffer(CharEntityEncoderFallback parent)
  86.         {
  87.             this.parent = parent;
  88.         }
  89.        
  90.         public override bool Fallback(char charUnknown, int index)
  91.         {
  92.             // If we are already in fallback, throw, it's probably at the suspect character in charEntity
  93.             if (charEntityIndex >= 0) {
  94.                 (new EncoderExceptionFallbackBuffer()).Fallback(charUnknown, index);
  95.             }
  96.            
  97.             // find out if we can replace the character with entity
  98.             if (parent.CanReplaceAt(index)) {
  99.                 // Create the replacement character entity
  100.                 charEntity = string.Format(CultureInfo.InvariantCulture, "&#x{0:X};", new object[] {(int)charUnknown});
  101.                 charEntityIndex = 0;
  102.                 return true;
  103.             }
  104.             else {
  105.                 EncoderFallbackBuffer errorFallbackBuffer = (new EncoderExceptionFallback()).CreateFallbackBuffer();
  106.                 errorFallbackBuffer.Fallback(charUnknown, index);
  107.                 return false;
  108.             }
  109.         }
  110.        
  111.         public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index)
  112.         {
  113.             // check input surrogate pair
  114.             if (!char.IsSurrogatePair(charUnknownHigh, charUnknownLow)) {
  115.                 throw XmlConvert.CreateInvalidSurrogatePairException(charUnknownHigh, charUnknownLow);
  116.             }
  117.            
  118.             // If we are already in fallback, throw, it's probably at the suspect character in charEntity
  119.             if (charEntityIndex >= 0) {
  120.                 (new EncoderExceptionFallbackBuffer()).Fallback(charUnknownHigh, charUnknownLow, index);
  121.             }
  122.            
  123.             if (parent.CanReplaceAt(index)) {
  124.                 // Create the replacement character entity
  125.                 charEntity = string.Format(CultureInfo.InvariantCulture, "&#x{0:X};", new object[] {char.ConvertToUtf32(charUnknownHigh, charUnknownLow)});
  126.                 charEntityIndex = 0;
  127.                 return true;
  128.             }
  129.             else {
  130.                 EncoderFallbackBuffer errorFallbackBuffer = (new EncoderExceptionFallback()).CreateFallbackBuffer();
  131.                 errorFallbackBuffer.Fallback(charUnknownHigh, charUnknownLow, index);
  132.                 return false;
  133.             }
  134.         }
  135.        
  136.         public override char GetNextChar()
  137.         {
  138.             if (charEntityIndex == -1) {
  139.                 return (char)0;
  140.             }
  141.             else {
  142.                 Debug.Assert(charEntityIndex < charEntity.Length);
  143.                 char ch = charEntity[charEntityIndex++];
  144.                 if (charEntityIndex == charEntity.Length) {
  145.                     charEntityIndex = -1;
  146.                 }
  147.                 return ch;
  148.             }
  149.         }
  150.        
  151.         public override bool MovePrevious()
  152.         {
  153.             if (charEntityIndex == -1) {
  154.                 return false;
  155.             }
  156.             else {
  157.                 Debug.Assert(charEntityIndex < charEntity.Length);
  158.                 if (charEntityIndex > 0) {
  159.                     charEntityIndex--;
  160.                     return true;
  161.                 }
  162.                 else {
  163.                     return false;
  164.                 }
  165.             }
  166.         }
  167.        
  168.        
  169.         public override int Remaining {
  170.             get {
  171.                 if (charEntityIndex == -1) {
  172.                     return 0;
  173.                 }
  174.                 else {
  175.                     return charEntity.Length - charEntityIndex;
  176.                 }
  177.             }
  178.         }
  179.        
  180.         public override void Reset()
  181.         {
  182.             charEntityIndex = -1;
  183.         }
  184.     }
  185. }

Developer Fusion