« 続々・アラートウィンドウへフォーカスを移さない | メイン | WMソースフィルタの構造 »

2005年10月21日

mixi Alert 開発日誌:: URLエンコーディング

    

WinINetのInternetCanonicalizeUrlを使ってエンコードしたらエンコードされていない。
どうやらこれは、WinINetで使う時に問題のないようにエンコードするだけのようだ。
仕方ないので、C++用の適当なものはないかと探すがないので作った。
時々使うと思うので、ここにメモ。
ソースは次の通り。

#include <string>
#include <vector>
#include <ctype.h>
void UrlEncode( const std::string &in, std::vector<char> &out )
{
    out.clear();
    out.reserve( in.size() * 3 + 1 );    // 最大長で確保
    for( std::string::const_iterator i = in.begin(); i != in.end(); ++i )
    {
        unsigned char c = static_cast<unsigned char>(*i);
        if(c == ' ' )
        {
            out.push_back('+');
        }
        else if( isalnum( c ) || c == '$' || c == '-' || c == '_' || c == '.' ||
            c == '!' || c == '*' || c == '\'' || c == '(' || c == ')' || c == ',' )
        {
            out.push_back(c);
        }
        else
        {
            out.push_back('%');
            unsigned char nibble = (c >> 4) & 0xF;
            out.push_back( nibble < 10 ? nibble + '0' : nibble - 10 + 'A' );
            nibble = c & 0xF;
            out.push_back( nibble < 10 ? nibble + '0' : nibble - 10 + 'A' );
        }
    }
    out.push_back('\0');
}

#ifdef __TEST__
#include <windows.h>
#include <shellapi.h>
#include <mlang.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "shell32.lib")
int wmain( int argc, wchar_t *argv[] )
{
    if( argc < 2 ) return 1;

    // mlan.dllのロードと関数ポインタの取得
    typedef HRESULT (CALLBACK* PCONVERTINETUNICODETOMULTIBYTE)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
    PCONVERTINETUNICODETOMULTIBYTE pConvertINetUnicodeToMultiByte = NULL;
    HMODULE                hMod = NULL;
    hMod = LoadLibrary(_T("mlang.dll"));
    pConvertINetUnicodeToMultiByte = reinterpret_cast<PCONVERTINETUNICODETOMULTIBYTE>( GetProcAddress(hMod, _T("ConvertINetUnicodeToMultiByte")) );

    // ConvertINetUnicodeToMultiByte用の変数準備
    DWORD    dwMode = 0;
    int        srcLen = static_cast<int>( wcslen(argv[1]) );
    char    outbuf[1024];
    int        destLen = 1024;
    if( pConvertINetUnicodeToMultiByte( &dwMode, CP_UTF8, argv[1], &srcLen, outbuf, &destLen ) == S_OK )
    {
        outbuf[destLen] = '\0';
        std::string in( outbuf );
        std::vector<char> out;
        UrlEncode( in, out );
        std::string url("http://www.google.co.jp/search?hl=ja&lr=lang_ja&q=");
        url += std::string(&(out.at(0)));
        ShellExecute( GetDesktopWindow(), "open", url.c_str(), NULL, NULL, SW_SHOWDEFAULT );
    }
    if(hMod) FreeLibrary(hMod);

    return 0;
}
#endif // __TEST__

__TEST__の部分は、コマンドラインで引数にとったものを使いGoogleで検索している。
mlang.dllのロード周りのエラーチェックなどはやっていない。
後、__TEST__の部分を動かすにはIE5.5以降が必要。



投稿者 Takenori : 2005年10月21日 10:28




comments powered by Disqus
Total : Today : Yesterday : なかのひと