/// <summary>
        /// シナリオファイルを読み込む
        /// </summary>
        /// <returns>シナリオファイルが読み込めたかどうか</returns>
        public bool LoadScenario()
        {
            //ReadJEncを利用してファイルの読み込み
            using (Hnx8.ReadJEnc.FileReader reader = new FileReader(this.File))
            {
                Hnx8.ReadJEnc.CharCode c = reader.Read(this.File);
                Console.WriteLine("-----------------------------------------------------------------------");
                Console.WriteLine("Loading ScenarioFile【{0}】...", this.File.Name);
                string text = reader.Text;
                if (c is CharCode.Text)
                {
                    //読み込んだファイルがテキスト
                    Console.WriteLine("Encoding: {0}", c.Name);
                    ScenarioGrammarParser parser = new ScenarioGrammarParser();

                    try
                    {
                        this.Data = parser.Parse(text);
                        Console.WriteLine("Parse Successful !");
                        return(true);
                    }
                    catch (NullReferenceException)
                    {
                        Console.Error.WriteLine("Scenario: 【{0}】header mismatched.", this.File.FullName);
                    }
                }
                else
                {
                    //テキストファイルではない
                    Console.Error.WriteLine("【{0}】is not text file.", this.File.FullName);
                }
            }
            Console.Error.WriteLine("Scenario Load Error");
            return(false);
        }
Ejemplo n.º 2
0
        ///// <summary>
        ///// 簡易エンコード判定
        ///// </summary>
        ///// <param name="filePath"></param>
        ///// <returns></returns>
        //public static Encoding GetEncoding(string filePath)
        //{
        //    int codepage = (int)Const.EncodingCodePage.ShiftJIS;

        //    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        //    {
        //        byte[] bs = new byte[1];
        //        fs.Read(bs, 0, bs.Length);

        //        if (bs.Length > 0)
        //        {
        //            if (bs[0] >= 161 && bs[0] <= 193)
        //                codepage = (int)Const.EncodingCodePage.EucJP;
        //            if (bs[0] >= 208 && bs[0] <= 239)
        //                codepage = (int)Const.EncodingCodePage.UTF8;
        //        }
        //        fs.Close();
        //    }
        //    // 判定できないときはshift-jisをとりあえず返す
        //    return Encoding.GetEncoding(codepage);
        //}

        /// <summary>
        /// ライブラリによるエンコード判定
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static Encoding GetEncoding(string filePath)
        {
            FileInfo file = new FileInfo(filePath);

            using (Hnx8.ReadJEnc.FileReader reader = new FileReader(file))
            {
                //判別読み出し実行
                Hnx8.ReadJEnc.CharCode c = reader.Read(file);
                Encoding enc             = c.GetEncoding();

                // これでも取れなかった場合はしょうがない
                return(enc != null ? enc : Encoding.Default);
            }
        }
Ejemplo n.º 3
0
        /// <summary>読み込んであるバイト配列のプリアンブル(BOMヘッダ/マジックナンバー)からファイル文字コード種類特定を試みる</summary>
        /// <param name="len">ファイルサイズ(未読込部分も含む。読み込み済サイズはthis.Lengthを参照)</param>
        /// <returns>確定した場合、ファイル文字コード種類。確定できなかった場合null</returns>
        protected virtual CharCode GetPreamble(long len)
        {
            //【0】ファイル先頭バイトからUTF文字コード(BOMつきUTF)を判定
            CharCode ret = CharCode.GetPreamble(this.Bytes, this.Length);

            //BOMテキストファイルと判定できず&ファイル先頭にバイナリファイル特徴の0x00が登場している場合、追加チェック
            if (ret == null && Array.IndexOf <byte>(this.Bytes, 0x00, 0, this.Length) >= 0)
            {     //UTF16Nの可能性がなければバイナリファイルとみなす
                if (ReadJEnc.SeemsUTF16N(this.Bytes, (int)len) == null)
                { //■バイナリ確定(マジックナンバーからファイル種類を決定)
                    return(FileType.GetBinaryType(this.Bytes, this.Length));
                }
            }
            return(ret); //■BOMから特定できた場合はBOMつきUTF(特定できなかった場合はnull)
        }
Ejemplo n.º 4
0
        /// <summary>
        /// シナリオファイルを読み込んで解析します。
        /// </summary>
        /// <returns>シナリオが正常に読み込めたかどうか</returns>
        public bool Load()
        {
            if (!File.Exists(FilePath))
            {
                //ファイルが存在しない
                Console.Error.WriteLine("Scenario: 【{0}】not found.", FileName);
                return(false);
            }

            //ReadJEncを利用してファイルの読み込み
            FileInfo file = new FileInfo(FilePath);

            using (Hnx8.ReadJEnc.FileReader reader = new FileReader(file))
            {
                Hnx8.ReadJEnc.CharCode c = reader.Read(file);
                Console.WriteLine("-----------------------------------------------------------------------");
                Console.WriteLine("Loading ScenarioFile【{0}】...", FileName);
                string text = reader.Text;
                if (c is CharCode.Text && Regex.IsMatch(text, @"BveTs\s*Scenario", RegexOptions.IgnoreCase))
                {
                    //読み込んだファイルがテキスト
                    Console.WriteLine("Encoding: {0}", c.Name);
                    ScenarioGrammarParser parser = new ScenarioGrammarParser();
                    parser.ErrorListener = ErrorListener;
                    try
                    {
                        this.Data = parser.Parse(text);
                        Console.WriteLine("Parse Successful !");
                        InitData();
                        return(true);
                    }
                    catch (NullReferenceException)
                    {
                        Console.Error.WriteLine("Scenario: 【{0}】header mismatched.", FileName);
                    }
                }
                else
                {
                    //テキストファイルではない
                    Console.Error.WriteLine("【{0}】is not text file.", FileName);
                }
            }
            Console.Error.WriteLine("Scenario Load Error");
            return(false);
        }
Ejemplo n.º 5
0
 /// <summary>引数指定文字コードとCP1252を判別対象とする際のコンストラクタ</summary>
 /// <param name="CharCode">このインスタンスで判別対象とするデフォルト文字コード</param>
 /// <param name="BOUND">通常文字/この文字コード固有の文字種範囲の境界</param>
 /// <param name="NODEF">
 /// 文字コード未定義の箇所をbitで表現した値
 /// <remarks>
 /// [0]=0x80-0x9Fの未定義箇所
 /// [1]=0xA0-0xBFの未定義箇所
 /// [2]=0xC0-0xDFの未定義箇所
 /// [3]=0xE0-0xFFの未定義箇所
 /// </remarks></param>
 internal SBCS(CharCode CharCode, int BOUND, params uint[] NODEF)
     : base(CharCode, null)
 {
     this.BOUND = BOUND;
     this.NODEF = NODEF;
 }
Ejemplo n.º 6
0
        // 文字コード判別メソッド================================================

        /// <summary>バイト配列を全走査し、文字コードを自動判別する</summary>
        /// <param name="bytes">判定対象のバイト配列</param>
        /// <param name="len">ファイルサイズ(バイト配列先頭からのデコード対象バイト数)</param>
        /// <param name="text">out 判別した文字コードにより取り出したテキスト文字列(非テキストならnull)</param>
        /// <returns>文字コード判別結果(非テキストならnull)</returns>
        public CharCode GetEncoding(byte[] bytes, int len, out string text)
        {
            if (len == 0)
            {   // ■空ファイルにつき非テキストと判断
                text = null;
                return(null);
            }

            byte b1 = bytes[0]; // 汎用バイトデータ読み取り変数初期化

            // 【1】7bit文字コードの範囲の走査(ASCII判定/非ASCII文字開始位置把握)、およびUTF16N/JISチェック
            JIS escapeSequenceChecker = null; // JISエスケープシーケンス評価
            int asciiEndPos           = 0;    // ループ変数、兼、非ASCII文字を初めて検出した位置

            while (b1 < DEL)                  // 非ASCII文字が出現したらループ脱出:b1にはあらかじめ読み込み済
            {
                if (b1 <= BINARY)
                {   // バイナリ文字検出:先頭2バイトでの検出ならUTF16Nの可能性をチェック、否ならバイナリ確定
                    CharCode ret = (asciiEndPos < 2 ? SeemsUTF16N(bytes, len) : null);
                    if (ret != null && (text = ret.GetString(bytes, len)) != null)
                    {   // UTF16Nデコード成功:非テキスト文字混入チェック
                        int i;
                        for (i = -3; i <= BINARY; i++)
                        {   // 0xFFFD,0xFFFE,0xFFFF,0~BINARY、DELが混入している場合は非テキストとみなす
                            if (text.IndexOf((char)i, 0, text.Length) != -1)
                            {
                                break;
                            }
                        }
                        if (i > BINARY && text.IndexOf((char)DEL, 0, text.Length) == -1)
                        {   // ■UTF16N確定(非テキスト文字混入なし)
                            return(ret);
                        }
                    }
                    text = null;
                    return(null); // ■バイナリ確定
                }
                if (b1 == 0x1B)
                {   // エスケープシーケンス判定(エスケープコード内容を読み飛ばす)
                    if (escapeSequenceChecker == null)
                    {
                        escapeSequenceChecker = new JIS(bytes, len, asciiEndPos);
                    }
                    asciiEndPos += escapeSequenceChecker.GetEncoding(asciiEndPos);
                }
                // 次の文字へ
                if ((++asciiEndPos) >= len)
                {     // 全文字チェック完了:非ASCII文字未検出、JISもしくはASCII
                    if (escapeSequenceChecker != null)
                    { // エスケープシーケンスに基づく文字コードが取得できるか確認
                        CharCode ret = escapeSequenceChecker.GetEncoding(out text);
                        if (ret != null)
                        {   // ■エスケープシーケンスに基づく文字コードで確定
                            return(ret);
                        }
                    }
                    else if (JIS.hasSOSI(bytes, len))
                    {     // SO,SIによるエスケープを検出した場合は、半角カナJISの可能性を判定
                        if (escapeSequenceChecker == null && (text = CharCode.JIS50222.GetString(bytes, len)) != null)
                        { // ■エスケープシーケンスなし、半角カナSOSIのみを使用したJISで確定
                            return(CharCode.JIS50222);
                        }
                    }
                    // ■ASCII確定(ただしデコード失敗時はバイナリ)
                    return(((text = CharCode.ASCII.GetString(bytes, len)) != null) ? CharCode.ASCII : null);
                }
                b1 = bytes[asciiEndPos];
            }

            // 【2】非ASCII文字を含む範囲の走査、CP1252系/UTF8/EUCチェック、JIS残チェック
            byte b2;
            int  cp1252Score   = 0;                                     // いずれも、可能性が否定されたらint.MinValueが設定される
            int  utfScore      = 0;
            int  eucScore      = (this.EUC == null ? int.MinValue : 0); // EUC検出対象なしなら最初からチェック対象外
            int  sjisScore     = 0;
            bool existsEUC0x8F = false;                                 // EUC補助漢字を見つけたらtrueを設定
            uint NODEF         = this.NODEF;                            // パフォーマンス改善のためローカル変数におろす

            for (int cp1252Pos = asciiEndPos; cp1252Pos < len;)         // cp1252Posの加算はロジック途中で随時実施
            {
                if (b1 == DEL)
                {   // 制御文字0x7F登場なら、ごくわずかなJISの可能性以外全消滅。JISの可能性を消しきれるか判定
                    cp1252Score = int.MinValue;
                    utfScore    = int.MinValue;
                    eucScore    = int.MinValue;
                    sjisScore   = int.MinValue;
                    if (escapeSequenceChecker == null || (cp1252Pos++) >= len || (b1 = bytes[cp1252Pos]) < 0x21 || b1 >= DEL)
                    {                 // JISエスケープ未出現 or ファイル末尾で2バイト目なし or 2バイト目が0x21-0x7E範囲外ならJISの可能性も否定
                        text = null;
                        return(null); // ■バイナリ確定
                    }
                }
                // CP1252系チェック&0x80以上の文字範囲の把握(notAsciiStartPos~cp1252Pos)。b1読込済
                int notAsciiStart = cp1252Pos;
                switch (cp1252Score)
                {
                case int.MinValue:     // CP1252系の可能性否定済み、非ASCII文字のスキップのみ実施
                    while (b1 > DEL && (++cp1252Pos) < len)
                    {
                        b1 = bytes[cp1252Pos];
                    }
                    break;

                default:                            // CP1252系可能性あり、定義外文字混入チェック&ポイント加算
                    while (b1 > DEL)
                    {                               // そのバイト値が未定義コードかどうかチェック(bit表現値とかみあうようビットシフトして照合)
                        if (b1 <= 0x9F && (NODEF & (1u << (b1 % 32))) != 0)
                        {                           // ビットが立ってる=未定義コード、可能性消滅
                            cp1252Score = int.MinValue;
                            goto case int.MinValue; // 非ASCII文字スキップへ
                        }
                        if ((++cp1252Pos) >= len)
                        {
                            break;
                        }
                        b1 = bytes[cp1252Pos];
                    }
                    // 非ASCII文字範囲終了、評価ポイント加算
                    // 1バイトのみ出現時(SJISよりもCP1252系の可能性が高い)、SJIS漢字1文字目と同評価・SJISカナよりも高評価となるようポイント加算
                    if (cp1252Pos == notAsciiStart + 1)
                    {
                        cp1252Score += 2;
                    }
                    else if (cp1252Pos == notAsciiStart + 2 && (b2 = bytes[cp1252Pos - 1]) >= 0xC0)
                    {       // 2バイトのみ出現時、ダイアクリティカルマーク(発音記号等)つきアルファベットなら配点補正
                        if (b2 == (b2 = bytes[cp1252Pos - 2]))
                        {
                            cp1252Score += 5;
                        }       // 同一文字重ねはかなり特徴的(SJISカナより可能性高)
                        else if (b2 >= 0xC0)
                        {       // 続きor直前のASCII文字がアルファベットっぽければ、SJISカナより可能性が高くなるよう補正
                            if (b1 > 0x40 || (notAsciiStart > 0 && bytes[notAsciiStart - 1] > 0x40))
                            {
                                cp1252Score += 5;
                            }
                            else
                            {
                                cp1252Score += 3;
                            }                              // どちらでもなければ、EUCよりは可能性高とする
                        }
                        else
                        {
                            cp1252Score++;
                        }                           // 否ならば低めの加算とする
                    }
                    else
                    {
                        cp1252Score++;
                    }                           // いずれにも該当しなければやや低めの加算とする
                    break;
                }
                // notAsciiStartPos~cp1252Pos範囲のUTF8チェック
                if (utfScore >= 0)
                {
                    bool prevIsKanji = false;
                    for (int utfPos = notAsciiStart; utfPos < cp1252Pos; utfPos++)
                    {
                        b1 = bytes[utfPos]; // ※1バイト目は厳密にチェック、2バイト目以降は(デコード時にチェックアウトできる前提で)冗長なエンコードやサロゲート等を許容している
                        // 1バイト目・2バイト目(ともに0x80以上であることは確認済み)をチェック
                        if (b1 < 0xC2 || (++utfPos) >= cp1252Pos || bytes[utfPos] > 0xBF)
                        {
                            utfScore = int.MinValue; break;
                        }   // UTF8可能性消滅
                        else if (b1 < 0xE0)
                        {   // 2バイト文字OK(半角文字とみなして評価)
                            if (prevIsKanji == false)
                            {
                                utfScore += 6;
                            }
                            else
                            {
                                utfScore += 2; prevIsKanji = false;
                            }
                        }
                        // 3バイト目(0x80以上であることは確認済み)をチェック
                        else if ((++utfPos) >= cp1252Pos || bytes[utfPos] > 0xBF)
                        {
                            utfScore = int.MinValue; break;
                        }   // UTF8可能性消滅
                        else if (b1 < 0xF0)
                        {   // 3バイト文字OK(全角文字とみなして評価)
                            if (prevIsKanji == true)
                            {
                                utfScore += 8;
                            }
                            else
                            {
                                utfScore += 4; prevIsKanji = true;
                            }
                        }
                        // 4バイト目(0x80以上であることは確認済み)をチェック
                        else if ((++utfPos) >= cp1252Pos || bytes[utfPos] > 0xBF)
                        {
                            utfScore = int.MinValue; break;
                        }   // UTF8可能性消滅
                        else if (b1 < 0xF5)
                        {   // 4バイト文字OK(全角文字とみなして評価)
                            if (prevIsKanji == true)
                            {
                                utfScore += 12;
                            }
                            else
                            {
                                utfScore += 6; prevIsKanji = true;
                            }
                        }
                        else
                        {
                            utfScore = int.MinValue; break;
                        }                                        // UTF8可能性消滅(0xF5以降はUTF8未定義)
                    }
                }
                // notAsciiStartPos~cp1252Pos範囲のEUCチェック ※EUCの文字コード範囲はEUC-JP/TW/CN/KRでほぼ共通
                if (eucScore >= 0)
                {                               // 前の文字との連続性チェック用定数定義
                    const int PREV_KANA    = 1; // 直前文字は半角カナ
                    const int PREV_ZENKAKU = 2; // 直前文字は全角
                    int       prevChar     = 0; // 前の文字はKANAでもZENKAKUでもない
                    for (int eucPos = notAsciiStart; eucPos < cp1252Pos; eucPos++)
                    {                           // 1バイト目(0xA1-0xFE,0x8E,0x8F)・2バイト目(1バイト目に応じ範囲が異なる)のチェック
                        b1 = bytes[eucPos];
                        if (b1 == 0xFF || (++eucPos) >= cp1252Pos)
                        {
                            eucScore = int.MinValue; break;
                        }                                                                              // EUC可能性消滅
                        b2 = bytes[eucPos];
                        if (b1 >= 0xA1)
                        {   // 1バイト目=全角文字指定、2バイト全角文字チェック
                            if (b2 < 0xA1 || b2 == 0xFF)
                            {
                                eucScore = int.MinValue; break;
                            }                                                                // EUC可能性消滅
                            // 2バイト文字OK(全角)
                            if (prevChar == PREV_ZENKAKU)
                            {
                                eucScore += 5;
                            }
                            else
                            {
                                eucScore += 2; prevChar = PREV_ZENKAKU;
                            }
                        }
                        else if (b1 == 0x8E)
                        {   // 1バイト目=EUC-JPのかな文字(orEUC-TWの4バイト文字)指定。2バイトの半角カナ文字チェック
                            if (b2 < 0xA1 || b2 > 0xDF)
                            {
                                eucScore = int.MinValue; break;
                            }                                                               // EUC可能性消滅
                            // 検出OK,EUC文字数を加算(半角文字)
                            if (prevChar == PREV_KANA)
                            {
                                eucScore += 6;
                            }
#if (!JPONLY)
                            // 漢字圏テキスト文字コードのうちEUC-TWに限り全角文字相当の扱いとする(0x8E,0xA2-0xB0,0xA1-0xFE,0xA1-0xFEの4バイト文字の判定に流用)
                            else if (this.EUC == CharCode.EUCTW)
                            {
                                if (prevChar == PREV_ZENKAKU)
                                {
                                    eucScore += 6;
                                }
                                else
                                {
                                    eucScore += 2; prevChar = PREV_ZENKAKU;
                                }
                            }
#endif
                            else
                            {
                                eucScore += 2; prevChar = PREV_KANA;
                            }
                        }
                        else if (b1 == 0x8F &&
                                 b2 >= 0xA1 && b2 < 0xFF &&
                                 (++eucPos) < cp1252Pos &&
                                 (b2 = bytes[eucPos]) >= 0xA1 && b2 < 0xFF)
                        {   // 残る可能性は3バイト文字:検出OKならEUC文字数を加算(全角文字、補助漢字)
                            if (prevChar == PREV_ZENKAKU)
                            {
                                eucScore += 8;
                            }
                            else
                            {
                                eucScore += 3; prevChar = PREV_ZENKAKU;
                            }
                            existsEUC0x8F = true; // ※補助漢字有
                        }
                        else
                        {
                            eucScore = int.MinValue; break;
                        }                                        // EUC可能性消滅
                    }
                }

                // ASCII文字範囲の読み飛ばし&バイナリチェック&JISチェック、b1に非ASCII文字出現位置のバイト値を格納
                while (cp1252Pos < len && (b1 = bytes[cp1252Pos]) < DEL)
                {
                    if (b1 <= BINARY)
                    {   // ■バイナリ確定
                        text = null;
                        return(null);
                    }
                    if (b1 == 0x1B)
                    {   // エスケープシーケンス判定(エスケープコード内容を読み飛ばす)
                        if (escapeSequenceChecker == null)
                        {
                            escapeSequenceChecker = new JIS(bytes, len, cp1252Pos);
                        }
                        cp1252Pos += escapeSequenceChecker.GetEncoding(cp1252Pos);
                    }
                    cp1252Pos++;
                }
            }

            // 【3】SJISなどの各国語文字コードチェック(非ASCII登場位置からチェック開始:ただしDEL検出時などは可能性なし)
            if (sjisScore != int.MinValue)
            {
                sjisScore = GetEncoding(bytes, asciiEndPos, len);
            }

            // 【4】ポイントに応じ文字コードを決定(実際にそのエンコーディングで読み出し成功すればOKとみなす)
            if (escapeSequenceChecker != null)
            {   // JIS系可能性高:エスケープシーケンスに基づく文字コードが取得できるか確認
                CharCode ret = escapeSequenceChecker.GetEncoding(out text);
                if (ret != null)
                {
                    return(ret);
                }                                // ■エスケープシーケンスに基づく文字コードで確定
            }
            if (eucScore > 0 && eucScore > sjisScore && eucScore > utfScore)
            {     // EUC可能性高
                if (cp1252Score > eucScore)
                { // ただし可能性が高ければCP1252系を先にチェック
                    if ((text = this.CP125X.GetString(bytes, len)) != null)
                    {
                        return(this.CP125X);
                    }                                                                               // ■CP1252系で読みこみ成功
                }
                if (existsEUC0x8F && (text = CharCode.EUCH.GetString(bytes, len)) != null)
                {
                    return(CharCode.EUCH);
                }                                                                                                   // ■EUC補助漢字読みこみ成功
                if ((text = this.EUC.GetString(bytes, len)) != null)
                {
                    return(this.EUC);
                }                                                                         // ■EUCで読みこみ成功
            }
            if (utfScore > 0 && utfScore >= sjisScore)
            {   // UTF可能性高
                if ((text = CharCode.UTF8N.GetString(bytes, len)) != null)
                {
                    return(CharCode.UTF8N);
                }                                                                                     // ■UTF-8Nで読みこみ成功
            }
            if (sjisScore >= 0)
            {   // SJISなどの各国語指定に合致したなら、そのコードでの読み出しを試みる(ただし可能性が高ければCP1252系を先にチェック)
                if (cp1252Score > sjisScore && (text = this.CP125X.GetString(bytes, len)) != null)
                {
                    return(this.CP125X);
                }                                                                                                          // ■CP1252系で読みこみ成功
                if ((text = this.CharCode.GetString(bytes, len)) != null)
                {
                    return(this.CharCode);
                }                                                                                   // ■各国語文字コードで読みこみ成功
            }
            if (cp1252Score > 0)
            {   // CP1252系の可能性のみ残っているのでチェック
                if ((text = this.CP125X.GetString(bytes, len)) != null)
                {
                    return(this.CP125X);
                }                                                                               // ■CP1252系で読みこみ成功
            }
            // ■いずれにも該当しなかった場合は、バイナリファイル扱いとする
            text = null;
            return(null);
        }
Ejemplo n.º 7
0
 /// <summary>CP1252系文字コードのみを判別対象とする際のコンストラクタ</summary>
 /// <param name="CP125X">CP1252系の判別対象デフォルト文字コード(CP1252以外を指定)</param>
 /// <param name="NODEF">0x80-0x9Fのうち文字コード未定義の箇所をbitで表現した値</param>
 protected ReadJEnc(CharCode CP125X, uint NODEF)
 {
     this.CharCode = CP125X;
     this.CP125X   = CP125X;
     this.NODEF    = NODEF;
 }
Ejemplo n.º 8
0
 /// <summary>引数指定文字コード/CP1252/EUCを判別対象とする際のコンストラクタ</summary>
 /// <param name="CharCode">このインスタンスで判別対象とするデフォルト文字コード</param>
 /// <param name="EUC">EUCの文字コード</param>
 protected ReadJEnc(CharCode CharCode, CharCode EUC)
 {
     this.CharCode = CharCode;
     this.EUC      = EUC;
 }
Ejemplo n.º 9
0
 /// <summary>基本コンストラクタ</summary>
 /// <param name="c">自動判別デフォルト文字コード</param>
 /// <param name="EUC">EUCの文字コード</param>
 protected ReadJEnc(CharCode c, CharCode EUC)
 {
     this.CharCode = c;
     this.EUC      = EUC;
 }