文字コードの変換(まだ続くの?)

巷で話題の ConvertINetString を利用したコードコンバータを作成しました。全体はこちらに公開してありますが、肝となる部分を挙げておきます。何かの参考にはなるだろうと思いますので。

static BOOL ConvertFromHandle( HANDLE hDst, HANDLE hSrc, DWORD FromCP, DWORD ToCP )
{
    BYTE buf[ 512 ], wbuf[ 4096 ];
    DWORD w, dwReaded;
    INT nSrcSize, nDstSize, i = 0;
    HRESULT r;
    DWORD cxt = 0;

    while( TRUE ){
        if( !ReadFile( hSrc, buf + i, sizeof( buf ) - i, &dwReaded, NULL ) ){
            dwReaded = 0;
        }
        dwReaded += i;
        if( dwReaded == 0 )break;
        nSrcSize = dwReaded;
        nDstSize = sizeof( wbuf ) - 1;
        r = ConvertINetString( &cxt, FromCP, ToCP, buf, (LPINT)&nSrcSize, wbuf, &nDstSize );
        if( r != S_OK ) return FALSE;
        PutData( hDst, wbuf, nDstSize );
        if( ( i = dwReaded - nSrcSize ) != 0 ) CopyMemory( buf, buf + nSrcSize, i );
    }
    return TRUE;
}

ISO-2022-JPEUC-JPの間で相互に変換できないというのは、umqさんの日記にあるとおり。いったんUnicodeに変換し、それを再度他のコードに変換する、という作業が必要になります。これは、IEがリモートから受け取った文字列を最終的にはCP932(Shift_JIS)に直すことを目的にしている、と考えれば納得できるものでもあります。

C:\> wiconv -f EUC-JP -t Unicode EUC-JP.TXT | wiconv -f Unicode -t ISO-2022-JP

また、-d オプションをつけることにより、変換した文字列をダンプして表示させることもできます。-t または -f を省略することによりOEMコードページ(普通は932)が指定されたものとみなされます。

C:\>echo あいうえお|wiconv -t EUC-JP -d
\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa\x0d\x0a

ダンプ結果に癖があるのはご愛嬌ということで。