The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.Runtime \ NumberFormatterBase

  1. //------------------------------------------------------------------------------
  2. // <copyright file="NumberFormatter.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.Diagnostics;
  16. using System.Text;
  17. namespace System.Xml.Xsl.Runtime
  18. {
  19.     using Res = System.Xml.Utils.Res;
  20.    
  21.     static internal class CharUtil
  22.     {
  23.         // Checks whether a given character is alphanumeric. Alphanumeric means any character that has
  24.         // a Unicode category of Nd (8), Nl (9), No (10), Lu (0), Ll (1), Lt (2), Lm (3) or Lo (4)
  25.         // <spec>http://www.w3.org/TR/xslt.html#convert</spec>
  26.         public static bool IsAlphaNumeric(char ch)
  27.         {
  28.             int category = (int)char.GetUnicodeCategory(ch);
  29.             return category <= 4 || (category <= 10 && category >= 8);
  30.         }
  31.        
  32.         // Checks whether a given character has decimal digit value of 1. The decimal digits are characters
  33.         // having the Unicode category of Nd (8). NOTE: We do not support Tamil and Ethiopic numbering systems
  34.         // having no zeros.
  35.         public static bool IsDecimalDigitOne(char ch)
  36.         {
  37.             int category = (int)char.GetUnicodeCategory(--ch);
  38.             return category == 8 && char.GetNumericValue(ch) == 0;
  39.         }
  40.     }
  41.    
  42.     internal enum NumberingSequence
  43.     {
  44.         Nil = -1,
  45.         FirstDecimal,
  46.         Arabic = FirstDecimal,
  47.         // 0x0031 -- 1, 2, 3, 4, ...
  48.         DArabic,
  49.         // 0xff11 -- Combines DbChar w/ Arabic
  50.         Hindi3,
  51.         // 0x0967 -- Hindi numbers
  52.         Thai2,
  53.         // 0x0e51 -- Thai numbers
  54.         FEDecimal,
  55.         // 0x4e00 -- FE numbering style (decimal numbers)
  56.         KorDbNum1,
  57.         // 0xc77c -- Korea (decimal)
  58.         LastNum = KorDbNum1,
  59.        
  60.         // Alphabetic numbering sequences (do not change order unless you also change _rgnfcToLab's order)
  61.         FirstAlpha,
  62.         UCLetter = FirstAlpha,
  63.         // 0x0041 -- A, B, C, D, ...
  64.         LCLetter,
  65.         // 0x0061 -- a, b, c, d, ...
  66.         UCRus,
  67.         // 0x0410 -- Upper case Russian alphabet
  68.         LCRus,
  69.         // 0x0430 -- Lower case Russian alphabet
  70.         Thai1,
  71.         // 0x0e01 -- Thai letters
  72.         Hindi1,
  73.         // 0x0915 -- Hindi vowels
  74.         Hindi2,
  75.         // 0x0905 -- Hindi consonants
  76.         Aiueo,
  77.         // 0xff71 -- Japan numbering style (SbChar)
  78.         DAiueo,
  79.         // 0x30a2 -- Japan - Combines DbChar w/ Aiueo
  80.         Iroha,
  81.         // 0xff72 -- Japan numbering style (SbChar)
  82.         DIroha,
  83.         // 0x30a4 -- Japan - Combines DbChar w/ Iroha// New defines for 97...
  84.         DChosung,
  85.         // 0x3131 -- Korea Chosung (DbChar)
  86.         Ganada,
  87.         // 0xac00 -- Korea
  88.         ArabicScript,
  89.         // 0x0623 -- BIDI AraAlpha for Arabic/Farsi/Urdu
  90.         LastAlpha = ArabicScript,
  91.        
  92.         // Special numbering sequences (includes peculiar alphabetic and numeric sequences)
  93.         FirstSpecial,
  94.         UCRoman = FirstSpecial,
  95.         // 0x0049 -- I, II, III, IV, ...
  96.         LCRoman,
  97.         // 0x0069 -- i, ii, iii, iv, ...
  98.         Hebrew,
  99.         // 0x05d0 -- BIDI Heb1 for Hebrew
  100.         DbNum3,
  101.         // 0x58f1 -- FE numbering style (similar to China2, some different characters)
  102.         ChnCmplx,
  103.         // 0x58f9 -- China (complex, traditional chinese, spell out numbers)
  104.         KorDbNum3,
  105.         // 0xd558 -- Korea (1-99)
  106.         Zodiac1,
  107.         // 0x7532 -- Taiwan/China (10 numbers)
  108.         Zodiac2,
  109.         // 0x5b50 -- Taiwan/China (12 numbers)
  110.         Zodiac3,
  111.         // 0x7532 -- Taiwan/China (Zodiac1 + Zodiac2)
  112.         LastSpecial = Zodiac3
  113.     }
  114.    
  115.     internal class NumberFormatterBase
  116.     {
  117.         protected const int MaxAlphabeticValue = int.MaxValue;
  118.         // Maximum value that can be represented
  119.         private const int MaxAlphabeticLength = 7;
  120.         // Number of letters needed to represent the maximum value
  121.         public static void ConvertToAlphabetic(StringBuilder sb, double val, char firstChar, int totalChars)
  122.         {
  123.             Debug.Assert(1 <= val && val <= MaxAlphabeticValue);
  124.             Debug.Assert(Math.Pow(totalChars, MaxAlphabeticLength) >= MaxAlphabeticValue);
  125.            
  126.             char[] letters = new char[MaxAlphabeticLength];
  127.             int idx = MaxAlphabeticLength;
  128.             int number = (int)val;
  129.            
  130.             while (number > totalChars) {
  131.                 int quot = --number / totalChars;
  132.                 letters[--idx] = (char)(firstChar + (number - quot * totalChars));
  133.                 number = quot;
  134.             }
  135.             letters[--idx] = (char)(firstChar + --number);
  136.             sb.Append(letters, idx, MaxAlphabeticLength - idx);
  137.         }
  138.        
  139.         protected const int MaxRomanValue = 32767;
  140.         private const string RomanDigitsUC = "IIVIXXLXCCDCM";
  141.         private const string RomanDigitsLC = "iivixxlxccdcm";
  142.        
  143.         // RomanDigit = { I IV V IX X XL L XC C CD D CM M }
  144.         private static readonly int[] RomanDigitValue = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400,
  145.         500, 900, 1000};
  146.        
  147.         public static void ConvertToRoman(StringBuilder sb, double val, bool upperCase)
  148.         {
  149.             Debug.Assert(1 <= val && val <= MaxRomanValue);
  150.            
  151.             int number = (int)val;
  152.             string digits = upperCase ? RomanDigitsUC : RomanDigitsLC;
  153.            
  154.             for (int idx = RomanDigitValue.Length; idx-- != 0;) {
  155.                 while (number >= RomanDigitValue[idx]) {
  156.                     number -= RomanDigitValue[idx];
  157.                     sb.Append(digits, idx, 1 + (idx & 1));
  158.                 }
  159.             }
  160.         }
  161.        
  162.         // Most of tables here were taken from MSXML sources and compared with the last
  163.         // CSS3 proposal available at http://www.w3.org/TR/2002/WD-css3-lists-20021107/
  164.        
  165.         // MSXML-, CSS3+
  166.         // CSS3 inserts two new characters U+3090, U+3091 before U+3092
  167.         private const string hiraganaAiueo = "あいうえおかきくけこ" + "さしすせそたちつてと" + "なにぬねのはひふへほ" + "まみむめもやゆよらり" + "るれろわをん";
  168.        
  169.         // MSXML-, CSS3+
  170.         private const string hiraganaIroha = "いろはにほへとちりぬ" + "るをわかよたれそつね" + "ならむうゐのおくやま" + "けふこえてあさきゆめ" + "みしゑひもせす";
  171.        
  172.         // MSXML+, CSS3+
  173.         // CSS3 inserts two new characters U+30F0, U+30F1 before U+30F2
  174.         private const string katakanaAiueo = "アイウエオカキクケコ" + "サシスセソタチツテト" + "ナニヌネノハヒフヘホ" + "マミムメモヤユヨラリ" + "ルレロワヲン";
  175.        
  176.         // MSXML+, CSS3+
  177.         // CSS3 removes last U+30F3 character
  178.         private const string katakanaIroha = "イロハニホヘトチリヌ" + "ルヲワカヨタレソツネ" + "ナラムウヰノオクヤマ" + "ケフコエテアサキユメ" + "ミシヱヒモセスン";
  179.        
  180.         // MSXML+, CSS3-
  181.         private const string katakanaAiueoHw = "アイウエオカキクケコ" + "サシスセソタチツテト" + "ナニヌネノハヒフヘホ" + "マミムメモヤユヨラリ" + "ルレロワヲン";
  182.        
  183.         // MSXML+, CSS3-
  184.         private const string katakanaIrohaHw = "イロハニホヘトチリヌ" + "ルヲワカヨタレソツネ" + "ナラムウヰノオクヤマ" + "ケフコエテアサキユメ" + "ミシヱヒモセスン";
  185.        
  186.         // MSXML+, CSS3-
  187.         // Unicode 4.0.0 spec: When used to represent numbers in decimal notation, zero
  188.         // is represented by U+3007. Otherwise, zero is represented by U+96F6.
  189.         private const string cjkIdeographic = "〇一二三四五六七八九";
  190.     }
  191. }

Developer Fusion