Codificação na Indy 10 e Delphi
-
21-12-2019 - |
Pergunta
Eu estou usando Indy 10 com o Delphi.Seguinte é o meu código que usa EncodeString
método de Indy para codificar uma cadeia de caracteres.
var
EncodedString : String;
StringToBeEncoded : String;
EncoderMIME: TIdEncoderMIME;
....
....
EncodedString := EncoderMIME.EncodeString(StringToBeEncoded);
Eu não estou sendo o valor correto na codificado picada.
Solução
Qual é o propósito de
IndyTextEncoding_OSDefault
?
Aqui está o código-fonte para 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 que despi-me para fora .net código condicional para uma questão de simplicidade.A maioria do código é organizar singleton segurança do thread.O real valor retornado é sintetizado por uma chamada para TIdMBCSEncoding.Create
.Vamos olhar para isso.
constructor TIdMBCSEncoding.Create;
begin
Create(CP_ACP, 0, 0);
end;
Novamente eu remover o código condicional que não se aplica para a sua configuração do Windows.Agora, CP_ACP
é o Umctive Code Pidade, o atual sistema Windows página de código ANSI.Isso, no Windows, pelo menos, IndyTextEncoding_OSDefault
é uma codificação para o atual sistema do Windows página de código ANSI.
Por que usar
IndyTextEncoding_OSDefault
dar o mesmo comportamento que meu Delphi 7 código?
Isso porque o Delphi 7 / Indy 9 código para TEncoderMIME.EncodeString
não executar qualquer código de página de transformação e MIME codifica a seqüência de caracteres de entrada como se fosse uma matriz de bytes.Desde o Delphi 7 seqüência é codificada no active página de código ANSI, isso tem o mesmo efeito que passar IndyTextEncoding_OSDefault
para TEncoderMIME.EncodeString
em sua versão Unicode do código.
Qual é a diferença entre
IndyTextEncoding_Default
eIndyTextEncoding_OSDefault
?
Aqui está o código-fonte para IndyTextEncoding_OSDefault
:
function IndyTextEncoding_Default: IIdTextEncoding;
var
LType: IdTextEncodingType;
begin
LType := GIdDefaultTextEncoding;
if LType = encIndyDefault then begin
LType := encASCII;
end;
Result := IndyTextEncoding(LType);
end;
Isso retorna uma codificação que é determinado pelo valor de GIdDefaultTextEncoding
.Por padrão, GIdDefaultTextEncoding
é encASCII
.E assim, por padrão, IndyTextEncoding_Default
produz uma codificação ASCII.
Além de tudo isso você deve estar se perguntando qual a codificação que você deseja utilizar.Depender de valores padrão deixa a mercê desses padrões.O que acontece se os padrões não fazer o que você quer fazer.Especialmente como os padrões não são codificações Unicode e assim apoiar apenas um número limitado de caracteres.E o que mais dependem das configurações do sistema.
Se você deseja codificar internacional de texto, você normalmente iria escolher para utilizar a codificação UTF-8.
Um outro ponto é que você está chamando EncodeString
como se fosse um método de instância, mas na verdade é um método de classe.Você pode remover EncoderMIME
e chamada de TEncoderMIME.EncodeString
.Ou manter EncoderMIME
e chamada de EncoderMIME.Encode
.