Ignore:
Timestamp:
12/21/11 11:46:25 (5 months ago)
Author:
murachi
Message:
  • コードが Shift JIS で保存されていたのを UTF-8 で保存し直した。
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sample/guessutf8.cpp

    r6 r15  
    11/** 
    22    @file   guessutf8.cpp 
    3     @brief  libiconv ‚ð—p‚¢‚½•¶ŽšƒZƒbƒgŽ©“®”Fޝˆ—‚̃Tƒ“ƒvƒ‹ (“à•”ƒR[ƒh UCS4 ”Å) 
     3    @brief  libiconv を用いた文字セット自動認識処理のサンプル (内部コード UCS4 版) 
    44    @author T.MURACHI (Toshiyuki Murayama) / (C)2010 Harapeko Inc. 
    55*/ 
     
    1515using namespace std; 
    1616 
    17 /// •¶Žš‚ðˆµ‚¤“à•”ƒR[ƒhŒ^ 
     17/// 文字を扱う内部コード型 
    1818typedef uint32_t ucs4_t; 
    1919typedef basic_string<ucs4_t, char_traits<ucs4_t>, allocator<ucs4_t> > ucs4string; 
    2020 
    2121/** 
    22     @brief  ƒfƒR[ƒhŽž—áŠOƒNƒ‰ƒX 
     22    @brief  デコード時例外クラス 
    2323*/ 
    2424class UcsDecoderException : public exception 
     
    3535 
    3636/** 
    37     @brief  ƒGƒ“ƒR[ƒhŽž—áŠOƒNƒ‰ƒX 
     37    @brief  エンコード時例外クラス 
    3838*/ 
    3939class UcsEncoderException : public exception 
     
    5050 
    5151/** 
    52     @brief ƒfƒR[ƒ_ƒNƒ‰ƒX 
    53      
    54     ƒtƒ@ƒCƒ‹‚©‚ç“ǂݍž‚ñ‚¾•¶Žš—ñƒf[ƒ^‚ðA“à•”ƒR[ƒh‚Ì•¶Žš—ñ‚ɕϊ·‚·‚éB 
    55     •ÏŠ·Žž‚ɁAŒ³‚Ì•¶Žš—ñƒf[ƒ^‚Ì•¶ŽšƒZƒbƒg‚ðŽ©“®”Fޝ‚·‚éB 
     52    @brief デコーダクラス 
     53     
     54    ファイルから読み込んだ文字列データを、内部コードの文字列に変換する。 
     55    変換時に、元の文字列データの文字セットを自動認識する。 
    5656*/ 
    5757class UcsDecoder 
     
    6161    size_t src_size; 
    6262     
    63     // ƒfƒtƒHƒ‹ƒgƒRƒ“ƒXƒgƒ‰ƒNƒ^AƒRƒs[ƒRƒ“ƒXƒgƒ‰ƒNƒ^A‘ã“ü‰‰ŽZŽq‚ÍŽg—p‹ÖŽ~ 
     63    // デフォルトコンストラクタ、コピーコンストラクタ、代入演算子は使用禁止 
    6464    UcsDecoder(); 
    6565    UcsDecoder(const UcsDecoder &); 
    6666    UcsDecoder &operator =(const UcsDecoder &); 
    6767     
    68     /// •¶ŽšƒR[ƒhƒZƒbƒg‚ÌƒŠƒXƒg 
     68    /// 文字コードセットのリスト 
    6969    static char const* const ENCODE_LIST[]; 
    7070     
     
    7676public: 
    7777    /** 
    78         @brief ƒRƒ“ƒXƒgƒ‰ƒNƒ^ 
    79         @param bytes    (I) ƒtƒ@ƒCƒ‹‚©‚ç“ǂݍž‚ñ‚¾•¶Žš—ñƒf[ƒ^ 
     78        @brief コンストラクタ 
     79        @param bytes    (I) ファイルから読み込んだ文字列データ 
    8080         
    81         ˆø”‚É“n‚³‚ꂽ•¶Žš—ñƒf[ƒ^‚Ì•¶ŽšƒZƒbƒg‚ð‰ðÍ‚µA UCS4 ‚Ì“à•”ƒR[ƒh‚𐶐¬‚·‚éB 
    82         UCS4 ƒeƒLƒXƒg‚É‚Í get() ƒƒ\ƒbƒh‚ɂăAƒNƒZƒX‚Å‚«‚éB 
     81        引数に渡された文字列データの文字セットを解析し、 UCS4 の内部コードを生成する。 
     82        UCS4 テキストには get() メソッドにてアクセスできる。 
    8383    */ 
    8484    UcsDecoder(char const* bytes) 
     
    9898     
    9999    /** 
    100         @brief “à•”ƒR[ƒhƒeƒLƒXƒg‚ðŽæ“¾‚·‚é 
    101         @return “à•”ƒR[ƒh‚ɕϊ·‚³‚ꂽƒeƒLƒXƒg‚Ì•¶Žš—ñƒIƒuƒWƒFƒNƒgB 
     100        @brief 内部コードテキストを取得する 
     101        @return 内部コードに変換されたテキストの文字列オブジェクト。 
    102102    */ 
    103103    ucs4string const& get() const { return result; } 
     
    109109 
    110110private: 
    111     // •¶ŽšƒZƒbƒg‚ð‰ðÍ‚·‚éB 
     111    // 文字セットを解析する。 
    112112    string guessEncodeType() const 
    113113    { 
     
    126126            for (;;) { 
    127127                size_t ret = iconv(iconv_handle, &from_current, &from_left, &to_current, &to_left); 
    128                 // ƒGƒ‰[–³‚µ 
     128                // エラー無し 
    129129                if (ret != static_cast<size_t>(-1)) 
    130130                    break; 
    131131                 
    132                 // ƒ}ƒ‹ƒ`ƒoƒCƒg‚̉ºˆÊƒIƒNƒeƒbƒh‚ªŒ‡‚¯‚Ä‚¢‚éê‡A 
    133                 // ƒf[ƒ^ƒ\[ƒX‚Í‚±‚±‚ŏI—¹‚µ‚Ä‚¢‚é‚Í‚¸‚Ȃ̂ŁAƒGƒ‰[‚̓JƒEƒ“ƒg‚¹‚¸I—¹B 
     132                // マルチバイトの下位オクテッドが欠けている場合、 
     133                // データソースはここで終了しているはずなので、エラーはカウントせず終了。 
    134134                if (errno == EINVAL) 
    135135                    break; 
     
    137137                switch (errno) { 
    138138                    case E2BIG: 
    139                         // o—͐æƒoƒbƒtƒ@‚̃TƒCƒY‚ª‘«‚è‚È‚¢B 
    140                         // •ÏŠ·Ž©‘Ì‚ª–Ú“I‚ł͂Ȃ¢‚̂ŁA‘±‚«‚͏㏑‚«‚·‚éB 
     139                        // 出力先バッファのサイズが足りない。 
     140                        // 変換自体が目的ではないので、続きは上書きする。 
    141141                        to_current = reinterpret_cast<char *>(&buf[0]); 
    142142                        to_left = src_size * sizeof(ucs4_t); 
    143143                        break; 
    144144                    case EILSEQ: 
    145                         // ‚ ‚蓾‚È‚¢ƒR[ƒh‚ªoŒ»B 
    146                         // ƒGƒ‰[‚ðƒJƒEƒ“ƒg‚µA‘±‚«‚©‚ç•ÏŠ·‚ðŒp‘±‚·‚éB 
     145                        // あり得ないコードが出現。 
     146                        // エラーをカウントし、続きから変換を継続する。 
    147147                        ill_seq_count++; 
    148148                        from_current++; 
     
    150150                        break; 
    151151                    case EBADF: 
    152                         // ‰½‚ç‚©‚Ì——R‚É‚æ‚è•ÏŠ·‚ÉŽ¸”sB’ʏí‚Í‚ ‚蓾‚È‚¢‚Í‚¸B 
     152                        // 何らかの理由により変換に失敗。通常はあり得ないはず。 
    153153                        iconv_close(iconv_handle); 
    154154                        throw UcsDecoderException("iconv faild"); 
    155155                    default: 
    156                         // –¢’è‹`‚̃Gƒ‰[”ԍ† 
     156                        // 未定義のエラー番号 
    157157                        iconv_close(iconv_handle); 
    158158                        throw UcsDecoderException("unknown error"); 
     
    161161            iconv_close(iconv_handle); 
    162162             
    163             // ƒGƒ‰[‚ªˆê‚‚à‚È‚¯‚ê‚Ίm’è 
     163            // エラーが一つもなければ確定 
    164164            if (ill_seq_count == 0) 
    165165                return *encode_type; 
     
    167167            ill_seq_count_map[*encode_type] = ill_seq_count; 
    168168        } 
    169         // ƒGƒ‰[‚̐”‚ªÅ‚à­‚È‚¢‚à‚Ì‚ðŒó•â‚Æ‚µ‚ĕԂ·B 
     169        // エラーの数が最も少ないものを候補として返す。 
    170170        string guess_code; 
    171171        int ill_seq_count = 0; 
     
    179179    } 
    180180     
    181     // Œ³ƒf[ƒ^‚Ì•¶ŽšƒZƒbƒg‚ðŽw’肵‚āA UCS4 “à•”ƒR[ƒhƒeƒLƒXƒg‚ɕϊ·‚·‚éB 
     181    // 元データの文字セットを指定して、 UCS4 内部コードテキストに変換する。 
    182182    void decodeToUcs4(const string &encode_type) 
    183183    { 
     
    193193        for (;;) { 
    194194            size_t ret = iconv(iconv_handle, &from_current, &from_left, &to_current, &to_left); 
    195             // ƒGƒ‰[–³‚µ 
     195            // エラー無し 
    196196            if (ret != static_cast<size_t>(-1)) 
    197197                break; 
    198198             
    199             // ƒ}ƒ‹ƒ`ƒoƒCƒg‚̉ºˆÊƒIƒNƒeƒbƒh‚ªŒ‡‚¯‚Ä‚¢‚éê‡A 
    200             // ƒf[ƒ^ƒ\[ƒX‚Í‚±‚±‚ŏI—¹‚µ‚Ä‚¢‚é‚Í‚¸‚Ȃ̂ŁA‚±‚±‚܂łŏI—¹B 
     199            // マルチバイトの下位オクテッドが欠けている場合、 
     200            // データソースはここで終了しているはずなので、ここまでで終了。 
    201201            if (errno == EINVAL) 
    202202                break; 
     
    204204            switch (errno) { 
    205205                case E2BIG: 
    206                     // o—͐æƒoƒbƒtƒ@‚̃TƒCƒY‚ª‘«‚è‚È‚¢B 
    207                     // ƒoƒbƒtƒ@‚ðŠg’£‚µAŒp‘±‚·‚éB 
     206                    // 出力先バッファのサイズが足りない。 
     207                    // バッファを拡張し、継続する。 
    208208                    { 
    209209                        size_t pre_size = buf.size(); 
     
    214214                    break; 
    215215                case EILSEQ: 
    216                     // ‚ ‚蓾‚È‚¢ƒR[ƒh‚ªoŒ»B 
    217                     // ƒGƒ‰[‚ð‰ñ”ð‚µA‘±‚«‚©‚ç•ÏŠ·‚ðŒp‘±‚·‚éB 
     216                    // あり得ないコードが出現。 
     217                    // エラーを回避し、続きから変換を継続する。 
    218218                    from_current++; 
    219219                    from_left--; 
    220220                    break; 
    221221                case EBADF: 
    222                     // ‰½‚ç‚©‚Ì——R‚É‚æ‚è•ÏŠ·‚ÉŽ¸”sB’ʏí‚Í‚ ‚蓾‚È‚¢‚Í‚¸B 
     222                    // 何らかの理由により変換に失敗。通常はあり得ないはず。 
    223223                    iconv_close(iconv_handle); 
    224224                    throw UcsDecoderException("iconv faild"); 
    225225                default: 
    226                     // –¢’è‹`‚̃Gƒ‰[”ԍ† 
     226                    // 未定義のエラー番号 
    227227                    iconv_close(iconv_handle); 
    228228                    throw UcsDecoderException("unknown error"); 
     
    249249 
    250250/** 
    251     @brief ƒGƒ“ƒR[ƒ_ƒNƒ‰ƒX 
    252      
    253     “à•”ƒR[ƒh‚Ì•¶Žš—ñ‚ðAUTF-8 Œ`Ž®‚Ì•¶Žš—ñƒf[ƒ^‚ɕϊ·‚·‚éB 
     251    @brief エンコーダクラス 
     252     
     253    内部コードの文字列を、UTF-8 形式の文字列データに変換する。 
    254254*/ 
    255255class UcsEncoder 
     
    258258    vector<char> result_bytes; 
    259259     
    260     // ƒfƒtƒHƒ‹ƒgƒRƒ“ƒXƒgƒ‰ƒNƒ^AƒRƒs[ƒRƒ“ƒXƒgƒ‰ƒNƒ^A‘ã“ü‰‰ŽZŽq‚ÍŽg—p‹ÖŽ~ 
     260    // デフォルトコンストラクタ、コピーコンストラクタ、代入演算子は使用禁止 
    261261    UcsEncoder(); 
    262262    UcsEncoder(const UcsEncoder &); 
     
    265265public: 
    266266    /** 
    267         @brief ƒRƒ“ƒXƒgƒ‰ƒNƒ^ 
    268         @param src  (I) UCS4 “à•”ƒR[ƒh•¶Žš—ñ 
     267        @brief コンストラクタ 
     268        @param src  (I) UCS4 内部コード文字列 
    269269         
    270         ˆø”‚É“n‚³‚ꂽ UCS4 “à•”ƒR[ƒh•¶Žš—ñ‚ðAUTF-8 Œ`Ž®‚Ì•¶Žš—ñƒf[ƒ^‚ɕϊ·‚·‚éB 
     270        引数に渡された UCS4 内部コード文字列を、UTF-8 形式の文字列データに変換する。 
    271271    */ 
    272272    UcsEncoder(const ucs4string &src) : ucs_text(src), result_bytes(src.size() + 1, '\0') 
     
    275275    } 
    276276    /** 
    277         @brief UTF-8 Œ`Ž®‚Ì•¶Žš—ñƒf[ƒ^‚ðŽæ“¾‚·‚é 
    278         @return UTF-8 Œ`Ž®‚Ì•¶Žš—ñƒf[ƒ^‚ւ̃|ƒCƒ“ƒ^ 
     277        @brief UTF-8 形式の文字列データを取得する 
     278        @return UTF-8 形式の文字列データへのポインタ 
    279279    */ 
    280280    char const* get() const { return &result_bytes[0]; } 
    281281     
    282282private: 
    283     // UCS4 “à•”ƒR[ƒh•¶Žš—ñ‚ð UTF-8 Œ`Ž®‚ɕϊ·‚·‚é 
     283    // UCS4 内部コード文字列を UTF-8 形式に変換する 
    284284    void encodeFromUcs4() 
    285285    { 
     
    293293        for (;;) { 
    294294            size_t ret = iconv(iconv_handle, &from_current, &from_left, &to_current, &to_left); 
    295             // ƒGƒ‰[–³‚µ 
     295            // エラー無し 
    296296            if (ret != static_cast<size_t>(-1)) 
    297297                break; 
    298298             
    299             // ƒ}ƒ‹ƒ`ƒoƒCƒg‚̉ºˆÊƒIƒNƒeƒbƒh‚ªŒ‡‚¯‚Ä‚¢‚éê‡A 
    300             // ƒf[ƒ^ƒ\[ƒX‚Í‚±‚±‚ŏI—¹‚µ‚Ä‚¢‚é‚Í‚¸‚Ȃ̂ŁA‚±‚±‚܂łŏI—¹B 
    301             // ¦‚ ‚肦‚È‚¢‚ªc 
     299            // マルチバイトの下位オクテッドが欠けている場合、 
     300            // データソースはここで終了しているはずなので、ここまでで終了。 
     301            // ※ありえないが… 
    302302            if (errno == EINVAL) 
    303303                break; 
     
    305305            switch (errno) { 
    306306                case E2BIG: 
    307                     // o—͐æƒoƒbƒtƒ@‚̃TƒCƒY‚ª‘«‚è‚È‚¢B 
    308                     // ƒoƒbƒtƒ@‚ðŠg’£‚µAŒp‘±‚·‚éB 
     307                    // 出力先バッファのサイズが足りない。 
     308                    // バッファを拡張し、継続する。 
    309309                    { 
    310310                        size_t pre_size = result_bytes.size(); 
     
    315315                    break; 
    316316                case EILSEQ: 
    317                     // ‚ ‚蓾‚È‚¢ƒR[ƒh‚ªoŒ»B 
    318                     // ƒGƒ‰[‚ð‰ñ”ð‚µA‘±‚«‚©‚ç•ÏŠ·‚ðŒp‘±‚·‚éB 
     317                    // あり得ないコードが出現。 
     318                    // エラーを回避し、続きから変換を継続する。 
    319319                    from_current++; 
    320320                    from_left--; 
    321321                    break; 
    322322                case EBADF: 
    323                     // ‰½‚ç‚©‚Ì——R‚É‚æ‚è•ÏŠ·‚ÉŽ¸”sB’ʏí‚Í‚ ‚蓾‚È‚¢‚Í‚¸B 
     323                    // 何らかの理由により変換に失敗。通常はあり得ないはず。 
    324324                    iconv_close(iconv_handle); 
    325325                    throw UcsEncoderException("iconv faild"); 
    326326                default: 
    327                     // –¢’è‹`‚̃Gƒ‰[”ԍ† 
     327                    // 未定義のエラー番号 
    328328                    iconv_close(iconv_handle); 
    329329                    throw UcsEncoderException("unknown error"); 
     
    337337{ 
    338338    try { 
    339         // •W€“ü—Í‚ðˆê‹C“ǂ݁c 
     339        // 標準入力を一気読み… 
    340340        vector<char> buf(32768, '\0'); 
    341341        char * target = &buf[0]; 
     
    353353            target = &buf[pre_size - 1]; 
    354354        } 
    355         // ƒfƒR[ƒh 
     355        // デコード 
    356356        ucs4string text = UcsDecoder(&buf[0]).get(); 
    357         // uAv‚ðu,v‚ɕϊ·‚·‚é 
     357        // 「、」を「,」に変換する 
    358358        for (size_t i = text.find_first_of(0x3001ul); i != ucs4string::npos; i = text.find_first_of(0x3001ul, i + 1)) 
    359359            text[i] = 0x2cul; 
    360         // uBv‚ðu.v‚ɕϊ·‚·‚é 
     360        // 「。」を「.」に変換する 
    361361        for (size_t i = text.find_first_of(0x3002ul); i != ucs4string::npos; i = text.find_first_of(0x3002ul, i + 1)) 
    362362            text[i] = 0x2eul; 
    363         // ƒGƒ“ƒR[ƒh‚µ‚ďo—Í 
     363        // エンコードして出力 
    364364        fputs(UcsEncoder(text).get(), stdout); 
    365365    } 
Note: See TracChangeset for help on using the changeset viewer.