1

私の環境はi386上のUbuntu12.04Linuxです。/var/lib/locales/supported.d/localUTF-8ロケールのみが(に)インストールされていることがわかります。

de_DE.UTF-8 UTF-8
en_US.UTF-8 UTF-8
~

今問題:

TIdIOHandler.InitComponentはTIdTextEncoding.Defaultを呼び出し、TIdTextEncoding.DefaultはTIdMBCSEncoding.Create('ASCII')を呼び出します。

そしてそこに、ライン

FMaxCharSize := GetByteCount(PWideChar(@cValue[0]), 2);

が実行され、GetByteCountがゼロを返します。これは発生しないはずです(ASCIIはシングルバイトエンコーディングであるため、期待値は1です)。

ゼロ値を返す場所は、IdGlobalの2288行目です。

if iconv(FFromUTF16, @LCharsPtr, @LCharCount, @LBytesPtr, {$IFNDEF KYLIX}@{$ENDIF}LByteCount) = size_t(-1) then
begin
  Result := 0;
  Exit;
end;

これは、UTF-16ロケールが欠落していることが原因である可能性がありますか?(最初の試みでUTF-16サポートのインストールに成功しませんでした。おそらく、この問題はLinux上の他のIndyユーザーにも見られました)

4

1 に答える 1

2

Indyは、複数のプラットフォーム間でIndyに実装するのが難しいプラットフォーム固有の変数に依存しているiconv()ため、現在、エラーを適切に処理していません(独自のエラーコードを直接返すように実装されていれば、これは問題になりません)。すべてのエラーが実際の失敗であるわけではありませんが、Indyはまだそれを認識していないため、すべてのエラーを失敗として扱います(例外を発生させるのではなく、失敗時に0を返す理由については、これはEmbarcaderoのクラスをモデルにしているため、APIである必要があるためです。 -互換性があります。これはIndy11)で変更されます。iconv()errnoiconv()iconv()GetByteCount()TIdTextEncodingSysUtils.TEncoding

ICONVはその文字セットをネイティブに実装することになっているので、OSにどのロケートがインストールされているかは問題ではありません。この場合、 ASCII範囲外であるためiconv()にコードポイント$10FFFDをUTF-16からASCIIに変換できないと思われTIdMBCSEncoding.Create()ます。これは、Indyがerrno失敗と部分的な変換を区別するために調べる必要があるケースの1つですが、現在はそうしていません。

回避策として、IdGlobal.pasを編集して、TIdTextEncoding.DefaultプロパティゲッターがTIdASCIIEncodingクラスの代わりにクラスを使用するようにすることができます。これTIdMBCSEncodingは、IndyにはICONVに依存しない独自のASCII実装があるためです。

{$IFDEF HAS_CLASSPROPERTIES}
class function TIdTextEncoding.GetDefault: TIdTextEncoding;
{$ELSE}
class function TIdTextEncoding.Default: TIdTextEncoding;
{$ENDIF}
var
  LEncoding: TIdTextEncoding;
begin
  if GIdDefaultEncoding = nil then
  begin
    {$IFDEF USE_ICONV}
    //LEncoding := TIdMBCSEncoding.Create('ASCII');
    LEncoding := TIdASCIIEncoding.Create;
    {$ELSE}
    ...
于 2012-07-26T22:07:12.413 に答える