Haruyuki Mohri

毛利春幸のブログです。

TIdURI::PathEncode()を使わずエンコーディング

Embarcadero C++Builderは TIdURIにPathEncode()や、URLEncode()など機能があります。
std::ostringstreamGetBytes()を使って同じような実装をしてみました。

#include <sstream>
#include <array>
#include <functional>
const std::string path_encoding(UnicodeString input_, TEncoding* enc_)
{
    std::function<bool(char)> fun1_{[](char c__)->bool{
            std::array<char, 7> arr_={'-', '_', '.', '~', '&', '$', '!'};
            for (auto a_: arr_) {
                if (a_ == c__)
                {
                    return true;
                }
            }
            return false;
        }};
    std::ostringstream out_;

    System::TArray__1<System::Byte> b1{enc_->GetBytes(input_)};
    for (auto bt: b1)
    {
        char c_ = static_cast<char>( bt);
        if ((c_ >= '0' && c_ <= '9') || (c_ >= 'a' && c_ <= 'z') || (c_ >= 'A' && c_ <= 'Z') || fun1_(c_))
        {
            out_ << c_;
        }
        else
        {
            char s1_[4];
            snprintf(s1_, sizeof(s1_), "%%%02x", c_ & 0xff);
            out_ << s1_;
        }
    }
    return out_.str();
}

TIdURI::PathEncode()と比較して正しいかどうかテスト.

#include <IdURI.hpp>
#include <assert.h>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    UnicodeString s_ = path_encoding(Edit1->Text,TEncoding::UTF8).c_str();
    UnicodeString s1_ = TIdURI::PathEncode(Edit1->Text, IndyTextEncoding_UTF8() );

    assert(SameText(s_.UpperCase(), s1_)==true);

    Memo1->Lines->Append(Edit1->Text + "  =  " + s_);
}
//---------------------------------------------------------------------------

いくつかのパターンでテストしてみましたが、全て試せてはいません。

参考URL

TIdURI::URLEncodeでURLをエンコードする – 山本隆の開発日誌