Encoding in Indy 10 and Delphi

江枫思渺然 提交于 2019-12-11 13:19:31

问题


I am using Indy 10 with Delphi. Following is my code which uses EncodeString method of Indy to encode a string.

var
  EncodedString : String;
  StringToBeEncoded : String;
  EncoderMIME: TIdEncoderMIME;
....
....
EncodedString := EncoderMIME.EncodeString(StringToBeEncoded);

I am not getting the correct value in encoded sting.


回答1:


What is the purpose of IndyTextEncoding_OSDefault?

Here's the source code for IndyTextEncoding_OSDefault.

function IndyTextEncoding_OSDefault: IIdTextEncoding;
begin
  if GIdOSDefaultEncoding = nil then begin
    LEncoding := TIdMBCSEncoding.Create;
    if InterlockedCompareExchangeIntf(IInterface(GIdOSDefaultEncoding), LEncoding, nil) <> nil then begin
      LEncoding := nil;
    end;
  end;
  Result := GIdOSDefaultEncoding;
end;

Note that I stripped out the .net conditional code for simplicity. Most of this code is to arrange singleton thread-safety. The actual value returned is synthesised by a call to TIdMBCSEncoding.Create. Let's look at that.

constructor TIdMBCSEncoding.Create;
begin
  Create(CP_ACP, 0, 0);
end;

Again I've remove conditional code that does not apply to your Windows setting. Now, CP_ACP is the Active Code Page, the current system Windows ANSI code page. So, on Windows at least, IndyTextEncoding_OSDefault is an encoding for the current system Windows ANSI code page.


Why did using IndyTextEncoding_OSDefault give the same behaviour as my Delphi 7 code?

That's because the Delphi 7 / Indy 9 code for TEncoderMIME.EncodeString does not perform any code page transformation and MIME encodes the input string as though it were a byte array. Since the Delphi 7 string is encoded in the active ANSI code page, this has the same effect as passing IndyTextEncoding_OSDefault to TEncoderMIME.EncodeString in your Unicode version of the code.


What is the difference between IndyTextEncoding_Default and IndyTextEncoding_OSDefault?

Here is the source code for IndyTextEncoding_OSDefault:

function IndyTextEncoding_Default: IIdTextEncoding;
var
  LType: IdTextEncodingType;
begin
  LType := GIdDefaultTextEncoding;
  if LType = encIndyDefault then begin
    LType := encASCII;
  end;
  Result := IndyTextEncoding(LType);
end;

This returns an encoding that is determined by the value of GIdDefaultTextEncoding. By default, GIdDefaultTextEncoding is encASCII. And so, by default, IndyTextEncoding_Default yields an ASCII encoding.


Beyond all this you should be asking yourself which encoding you want to be using. Relying on default values leaves you at the mercy of those defaults. What if those defaults don't do what you want to do. Especially as the defaults are not Unicode encodings and so support only a limited range of characters. And what's more are dependent on system settings.

If you wish to encode international text, you would normally choose to use the UTF-8 encoding.


One other point to make is that you are calling EncodeString as though it were an instance method, but it is actually a class method. You can remove EncoderMIME and call TEncoderMIME.EncodeString. Or keep EncoderMIME and call EncoderMIME.Encode.



来源:https://stackoverflow.com/questions/25030477/encoding-in-indy-10-and-delphi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!