HebrewNumber.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Globalization / HebrewNumber.cs / 1 / HebrewNumber.cs

                            namespace System.Globalization { 
    using System;
    using System.Text;

    //////////////////////////////////////////////////////////////////////////// 
    //
    // Used in HebrewNumber.ParseByChar to maintain the context information ( 
    // the state in the state machine and current Hebrew number values, etc.) 
    // when parsing Hebrew number character by character.
    // 
    ////////////////////////////////////////////////////////////////////////////

    internal struct HebrewNumberParsingContext {
        // The current state of the state machine for parsing Hebrew numbers. 
        internal HebrewNumber.HS state;
        // The current value of the Hebrew number. 
        // The final value is determined when state is FoundEndOfHebrewNumber. 
        internal int result;
 
        public HebrewNumberParsingContext(int result) {
            // Set the start state of the state machine for parsing Hebrew numbers.
            state = HebrewNumber.HS.Start;
            this.result = 0; 
        }
    } 
 
    ////////////////////////////////////////////////////////////////////////////
    // 
    // Please see ParseByChar() for comments about different states defined here.
    //
    ////////////////////////////////////////////////////////////////////////////
 
    internal enum HebrewNumberParsingState {
        InvalidHebrewNumber, 
        NotHebrewDigit, 
        FoundEndOfHebrewNumber,
        ContinueParsing, 
    }

    ////////////////////////////////////////////////////////////////////////////
    // 
    // class HebrewNumber
    // 
    //  Provides static methods for formatting integer values into 
    //  Hebrew text and parsing Hebrew number text.
    // 
    //  Limitations:
    //      Parse can only handles value 1 ~ 999.
    //      ToString() can only handles 1 ~ 999. If value is greater than 5000,
    //      5000 will be subtracted from the value. 
    //
    //////////////////////////////////////////////////////////////////////////// 
 
    internal class HebrewNumber {
 
        // This class contains only static methods.  Add a private ctor so that
        // compiler won't generate a default one for us.
        private HebrewNumber() {
        } 

        //////////////////////////////////////////////////////////////////////////// 
        // 
        //  ToString
        // 
        //  Converts the given number to Hebrew letters according to the numeric
        //  value of each Hebrew letter.  Basically, this converts the lunar year
        //  and the lunar month to letters.
        // 
        //  The character of a year is described by three letters of the Hebrew
        //  alphabet, the first and third giving, respectively, the days of the 
        //  weeks on which the New Year occurs and Passover begins, while the 
        //  second is the initial of the Hebrew word for defective, normal, or
        //  complete. 
        //
        //  Defective Year : Both Heshvan and Kislev are defective (353 or 383 days)
        //  Normal Year    : Heshvan is defective, Kislev is full  (354 or 384 days)
        //  Complete Year  : Both Heshvan and Kislev are full      (355 or 385 days) 
        //
        //////////////////////////////////////////////////////////////////////////// 
 
        internal static String ToString(int Number) {
            char cTens = '\x0'; 
            char cUnits;               // tens and units chars
            int Hundreds, Tens;              // hundreds and tens values
            StringBuilder szHebrew = new StringBuilder();
 

            // 
            //  Adjust the number if greater than 5000. 
            //
            if (Number > 5000) { 
                Number -= 5000;
            }

            BCLDebug.Assert(Number > 0 && Number <= 999, "Number is out of range.");; 

            // 
            //  Get the Hundreds. 
            //
            Hundreds = Number / 100; 

            if (Hundreds > 0) {
                Number -= Hundreds * 100;
                // \x05e7 = 100 
                // \x05e8 = 200
                // \x05e9 = 300 
                // \x05ea = 400 
                // If the number is greater than 400, use the multiples of 400.
                for (int i = 0; i < (Hundreds / 4) ; i++) { 
                    szHebrew.Append('\x05ea');
                }

                int remains = Hundreds % 4; 
                if (remains > 0) {
                    szHebrew.Append((char)((int)'\x05e6' + remains)); 
                } 
            }
 
            //
            //  Get the Tens.
            //
            Tens = Number / 10; 
            Number %= 10;
 
            switch (Tens) { 
                case ( 0 ) :
                    cTens = '\x0'; 
                    break;
                case ( 1 ) :
                    cTens = '\x05d9';          // Hebrew Letter Yod
                    break; 
                case ( 2 ) :
                    cTens = '\x05db';          // Hebrew Letter Kaf 
                    break; 
                case ( 3 ) :
                    cTens = '\x05dc';          // Hebrew Letter Lamed 
                    break;
                case ( 4 ) :
                    cTens = '\x05de';          // Hebrew Letter Mem
                    break; 
                case ( 5 ) :
                    cTens = '\x05e0';          // Hebrew Letter Nun 
                    break; 
                case ( 6 ) :
                    cTens = '\x05e1';          // Hebrew Letter Samekh 
                    break;
                case ( 7 ) :
                    cTens = '\x05e2';          // Hebrew Letter Ayin
                    break; 
                case ( 8 ) :
                    cTens = '\x05e4';          // Hebrew Letter Pe 
                    break; 
                case ( 9 ) :
                    cTens = '\x05e6';          // Hebrew Letter Tsadi 
                    break;
            }

            // 
            //  Get the Units.
            // 
            cUnits = (char)(Number > 0 ? ((int)'\x05d0' + Number - 1) : 0); 

            if ((cUnits == '\x05d4') &&            // Hebrew Letter He  (5) 
                (cTens == '\x05d9')) {              // Hebrew Letter Yod (10)
                cUnits = '\x05d5';                 // Hebrew Letter Vav (6)
                cTens  = '\x05d8';                 // Hebrew Letter Tet (9)
            } 

            if ((cUnits == '\x05d5') &&            // Hebrew Letter Vav (6) 
                (cTens == '\x05d9')) {               // Hebrew Letter Yod (10) 
                cUnits = '\x05d6';                 // Hebrew Letter Zayin (7)
                cTens  = '\x05d8';                 // Hebrew Letter Tet (9) 
            }

            //
            //  Copy the appropriate info to the given buffer. 
            //
 
            if (cTens != '\x0') { 
                szHebrew.Append(cTens);
            } 

            if (cUnits != '\x0') {
                szHebrew.Append(cUnits);
            } 

            if (szHebrew.Length > 1) { 
                szHebrew.Insert(szHebrew.Length - 1, '"'); 
            } else {
                szHebrew.Append('\''); 
            }

            //
            //  Return success. 
            //
            return (szHebrew.ToString()); 
        } 

        //////////////////////////////////////////////////////////////////////////// 
        //
        // Token used to tokenize a Hebrew word into tokens so that we can use in the
        // state machine.
        // 
        ////////////////////////////////////////////////////////////////////////////
 
        enum HebrewToken { 
            Invalid = -1,
            Digit400 = 0, 
            Digit200_300 = 1,
            Digit100 = 2,
            Digit10 = 3,    // 10 ~ 90
            Digit1 = 4,     // 1, 2, 3, 4, 5, 8, 
            Digit6_7 = 5,
            Digit7 = 6, 
            Digit9 = 7, 
            SingleQuote = 8,
            DoubleQuote = 9, 
        };

        ////////////////////////////////////////////////////////////////////////////
        // 
        // This class is used to map a token into its Hebrew digit value.
        // 
        //////////////////////////////////////////////////////////////////////////// 

        class HebrewValue { 
            internal HebrewToken token;
            internal int value;
            internal HebrewValue(HebrewToken token, int value) {
                this.token = token; 
                this.value = value;
            } 
        } 

        // 
        // Map a Hebrew character from U+05D0 ~ U+05EA to its digit value.
        // The value is -1 if the Hebrew character does not have a associated value.
        //
        static HebrewValue[] HebrewValues = { 
            new HebrewValue(HebrewToken.Digit1, 1) , // '\x05d0
            new HebrewValue(HebrewToken.Digit1, 2) , // '\x05d1 
            new HebrewValue(HebrewToken.Digit1, 3) , // '\x05d2 
            new HebrewValue(HebrewToken.Digit1, 4) , // '\x05d3
            new HebrewValue(HebrewToken.Digit1, 5) , // '\x05d4 
            new HebrewValue(HebrewToken.Digit6_7,6) , // '\x05d5
            new HebrewValue(HebrewToken.Digit6_7,7) , // '\x05d6
            new HebrewValue(HebrewToken.Digit1, 8) , // '\x05d7
            new HebrewValue(HebrewToken.Digit9, 9) , // '\x05d8 
            new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9;          // Hebrew Letter Yod
            new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da; 
            new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db;          // Hebrew Letter Kaf 
            new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc;          // Hebrew Letter Lamed
            new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd; 
            new HebrewValue(HebrewToken.Digit10, 40) , // '\x05de;          // Hebrew Letter Mem
            new HebrewValue(HebrewToken.Invalid, -1) , // '\x05df;
            new HebrewValue(HebrewToken.Digit10, 50) , // '\x05e0;          // Hebrew Letter Nun
            new HebrewValue(HebrewToken.Digit10, 60) , // '\x05e1;          // Hebrew Letter Samekh 
            new HebrewValue(HebrewToken.Digit10, 70) , // '\x05e2;          // Hebrew Letter Ayin
            new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e3; 
            new HebrewValue(HebrewToken.Digit10, 80) , // '\x05e4;          // Hebrew Letter Pe 
            new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e5;
            new HebrewValue(HebrewToken.Digit10, 90) , // '\x05e6;          // Hebrew Letter Tsadi 
            new HebrewValue(HebrewToken.Digit100, 100) , // '\x05e7;
            new HebrewValue(HebrewToken.Digit200_300, 200) , // '\x05e8;
            new HebrewValue(HebrewToken.Digit200_300, 300) , // '\x05e9;
            new HebrewValue(HebrewToken.Digit400, 400) , // '\x05ea; 
        };
 
        const int minHebrewNumberCh = 0x05d0; 
        static char maxHebrewNumberCh = (char)(minHebrewNumberCh + HebrewValues.Length - 1);
 
        ////////////////////////////////////////////////////////////////////////////
        //
        // Hebrew number parsing State
        // The current state and the next token will lead to the next state in the state machine. 
        // DQ = Double Quote
        // 
        //////////////////////////////////////////////////////////////////////////// 

        internal enum HS { 
            _err = -1,          // an error state
            Start = 0,
            S400 = 1,           // a Hebrew digit 400
            S400_400 = 2,       // Two Hebrew digit 400 
            S400_X00 = 3,       // Two Hebrew digit 400 and followed by 100
            S400_X0  = 4,       // Hebrew digit 400 and followed by 10 ~ 90 
            X00_DQ = 5,         // A hundred number and followed by a double quote. 
            S400_X00_X0 = 6,
            X0_DQ = 7,          // A two-digit number and followed by a double quote. 
            X = 8,              // A single digit Hebrew number.
            X0  = 9,            // A two-digit Hebrew number
            X00 = 10,           // A three-digit Hebrew number
            S400_DQ = 11,       // A Hebrew digit 400 and followed by a double quote. 
            S400_400_DQ = 12,
            S400_400_100 = 13, 
            S9 = 14,            // Hebrew digit 9 
            X00_S9 = 15,        // A hundered number and followed by a digit 9
            S9_DQ = 16,         // Hebrew digit 9 and followed by a double quote 
            END = 100,          // A terminial state is reached.
        }

        // 
        // The state machine for Hebrew number pasing.
        // 
        static HS[][] m_numberPasingState = { 
                           // 400            300/200         100             90~10           8~1      6,       7,       9,          '           "
    /* 0 */             new HS[] {HS.S400,       HS.X00,         HS.X00,         HS.X0,          HS.X,    HS.X,    HS.X,    HS.S9,      HS._err,    HS._err}, 
    /* 1: S400 */       new HS[] {HS.S400_400,   HS.S400_X00,    HS.S400_X00,    HS.S400_X0,     HS._err, HS._err, HS._err, HS.X00_S9  ,HS.END,     HS.S400_DQ},
    /* 2: S400_400 */   new HS[] {HS._err,       HS._err,        HS.S400_400_100,HS.S400_X0,     HS._err, HS._err, HS._err, HS.X00_S9  ,HS._err,    HS.S400_400_DQ},
    /* 3: S400_X00 */   new HS[] {HS._err,       HS._err,        HS._err,        HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9  ,HS._err,    HS.X00_DQ},
    /* 4: S400_X0 */    new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS._err, HS._err, HS._err, HS._err,    HS._err,    HS.X0_DQ}, 
    /* 5: X00_DQ */     new HS[] {HS._err,       HS._err,        HS._err,        HS.END,         HS.END,  HS.END,  HS.END,  HS.END,     HS._err,    HS._err},
    /* 6: S400_X00_X0 */new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS._err, HS._err, HS._err, HS._err,    HS._err,    HS.X0_DQ}, 
    /* 7: X0_DQ */      new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS.END,  HS.END,  HS.END,  HS.END,     HS._err,    HS._err}, 
    /* 8: X */          new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS._err, HS._err, HS._err, HS._err,    HS.END,     HS._err},
    /* 9: X0 */         new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS._err, HS._err, HS._err, HS._err,    HS.END,     HS.X0_DQ}, 
    /* 10: X00 */       new HS[] {HS._err,       HS._err,        HS._err,        HS.S400_X0,     HS._err, HS._err, HS._err, HS.X00_S9,  HS.END,     HS.X00_DQ},
    /* 11: S400_DQ */   new HS[] {HS.END,        HS.END,         HS.END,         HS.END,         HS.END,  HS.END,  HS.END,  HS.END, HS._err,    HS._err},
    /* 12: S400_400_DQ*/new HS[] {HS._err,       HS._err,        HS.END,         HS.END,         HS.END,  HS.END,  HS.END,  HS.END, HS._err,    HS._err},
    /* 13: S400_400_100*/new HS[]{HS._err,       HS._err,        HS._err,        HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9,  HS._err,    HS.X00_DQ}, 
    /* 14: S9 */        new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS._err, HS._err, HS._err, HS._err,HS.END,    HS.S9_DQ},
    /* 15: X00_S9 */    new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS._err, HS._err, HS._err, HS._err,    HS._err,    HS.S9_DQ}, 
    /* 16: S9_DQ */     new HS[] {HS._err,       HS._err,        HS._err,        HS._err,        HS._err, HS.END,  HS.END,  HS._err,    HS._err,    HS._err}, 
    };
 
        ////////////////////////////////////////////////////////////////////////
        //
        // Actions:
        //  Parse a Hebrew number string. 
        // Returns:
        //      -1 if this is not a valid Hebrew string. 
        //      Otherwise, a positive number is returned. 
        // Limitations:
        //      The state machine only parses Hebrew number from 1 ~ 999. 
        //
        ////////////////////////////////////////////////////////////////////////
        /*
        internal static int Parse(String str) { 
            BCLDebug.Assert(str != null, "str != null");
            HebrewNumberParsingContext context = new HebrewNumberParsingContext(); 
 
            HebrewNumberParsingState result = 0;
            int i; 
            for (i = 0; i < str.Length; i++) {
                result = ParseByChar(str[i], context);
                if (result == HebrewNumberParsingState.NotHebrewDigit || result == HebrewNumberParsingState.InvalidHebrewNumber) {
                    return (-1); 
                }
                if (result == HebrewNumberParsingState.FoundEndOfHebrewNumber) { 
                    // Reach the terminal state. 
                    break;
                } 
            }
            if (result == HebrewNumberParsingState.FoundEndOfHebrewNumber && i == str.Length - 1) {
                return (context.result);
            } 
            // There are still characters left in the string or a terminal state is not reached.
            return (-1); 
        } 
        */
 
        ////////////////////////////////////////////////////////////////////////
        //
        //  Actions:
        //      Parse the Hebrew number by passing one character at a time. 
        //      The state between characters are maintained at HebrewNumberPasingContext.
        //  Returns: 
        //      Return a enum of HebrewNumberParsingState. 
        //          NotHebrewDigit: The specified ch is not a valid Hebrew digit.
        //          InvalidHebrewNumber: After parsing the specified ch, it will lead into 
        //              an invalid Hebrew number text.
        //          FoundEndOfHebrewNumber: A terminal state is reached.  This means that
        //              we find a valid Hebrew number text after the specified ch is parsed.
        //          ContinueParsing: The specified ch is a valid Hebrew digit, and 
        //              it will lead into a valid state in the state machine, we should
        //              continue to parse incoming characters. 
        // 
        ////////////////////////////////////////////////////////////////////////
 
        internal static HebrewNumberParsingState ParseByChar(char ch, ref HebrewNumberParsingContext context) {
            HebrewToken token;
            if (ch == '\'') {
                token = HebrewToken.SingleQuote; 
            } else if (ch == '\"') {
                token = HebrewToken.DoubleQuote; 
            } else { 
                int index = (int)ch - minHebrewNumberCh;
                if (index >= 0 && index < HebrewValues.Length ) { 
                    token = HebrewValues[index].token;
                    if (token == HebrewToken.Invalid) {
                        return (HebrewNumberParsingState.NotHebrewDigit);
                    } 
                    context.result += HebrewValues[index].value;
                } else { 
                    // Not in valid Hebrew digit range. 
                    return (HebrewNumberParsingState.NotHebrewDigit);
                } 
            }
            context.state = m_numberPasingState[(int)context.state][(int)token];
            if (context.state == HS._err) {
                // Invalid Hebrew state.  This indicates an incorrect Hebrew number. 
                return (HebrewNumberParsingState.InvalidHebrewNumber);
            } 
            if (context.state == HS.END) { 
                // Reach a terminal state.
                return (HebrewNumberParsingState.FoundEndOfHebrewNumber); 
            }
            // We should continue to parse.
            return (HebrewNumberParsingState.ContinueParsing);
        } 

        //////////////////////////////////////////////////////////////////////// 
        // 
        // Actions:
        //  Check if the ch is a valid Hebrew number digit. 
        //  This function will return true if the specified char is a legal Hebrew
        //  digit character, single quote, or double quote.
        // Returns:
        //  true if the specified character is a valid Hebrew number character. 
        //
        //////////////////////////////////////////////////////////////////////// 
 
        internal static bool IsDigit(char ch) {
            if (ch >= minHebrewNumberCh && ch <= maxHebrewNumberCh) { 
                return (HebrewValues[ch - minHebrewNumberCh].value >= 0);
            }
            return (ch == '\'' || ch == '\"');
        } 

    } 
}
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK