Universal Character Set Detector C LibraryをC++Builder XEから使用する

Mozillaエンコーディング自動判別ライブラリである「universalchardet」をDLL化したのをC++Builderで動作させてみました。

C++Builderでの修正箇所はprmem.hの「#include 」を「#include 」にするだけ。アーカイブはhttp://a7m.sakura.ne.jp/SOURCE/universalchardet-CB.7zに用意しました。

C++Builderでの使い方は以下の通り。TMemoryStreamのバッファとかをそのまま渡せる。

  // ファイルを読み込んでから
  std::unique_ptr<TMemoryStream> pBuffer(new TMemoryStream());
  pBuffer->LoadFromFile(FileName);
  pBuffer->Position = 0;

  char encoding[CHARDET_MAX_ENCODING_NAME];
  size_t len;
  int res = 0;
  chardet_t det = NULL;

  // エンコーディングの判別をする
  chardet_create(&det);
  res = chardet_handle_data(det, static_cast<const char*>(pBuffer->Memory), pBuffer->Size);
  chardet_data_end(det);

  // エンコーディング名の取得
  chardet_get_charset(det, encoding, CHARDET_MAX_ENCODING_NAME);
  chardet_destroy(det);

  // 自動判別結果を元にエンコーディングを判別して読み込み
  TEncoding* pEncoding = NULL;
  try {
    pEncoding = TEncoding::GetEncoding(encoding);
  } catch (EEncodingError& err) {
    pEncoding = TEncoding::GetEncoding(GetACP());
  }
  pStringList->Clear();
  pStringList->Lines->LoadFromStream(pBuffer.get(), pEncoding);

  // 後始末
  delete pEncoding;

注意点として、TEncoding::GetEncodingが文字列"EUC-JP"を判別してくれないので、EUC-JP(CP51932)を扱う場合はCP20932で代替するしかないので、その処理を入れる必要があるかも。