program Rfc2047;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.StrUtils,
IdException,
IdGlobal,
IdCharsets,
IdCoder,
IdCoderQuotedPrintable,
IdCoderMIME;
function Decode(
const AStr:
string; AIsHeader: Boolean = false ):
string;
function TryDecode(
const encoded_str:
string;
out decoded_text:
string ): Boolean;
var
parts: TArray<
string>;
charset, coding, encoded_text:
string;
encoding: IIdTextEncoding;
coder: TIdDecoder;
coderclass: TIdDecoderClass;
begin
parts := encoded_str.Split( ['
?'] );
if Length( parts ) <> 3
then
begin
Exit( false );
end;
charset := parts[0];
coding := parts[1].ToLowerInvariant( );
encoded_text := parts[2];
try
encoding := IndyTextEncoding( charset );
except
on E: EIdException
do
begin
Exit( false )
end;
end;
if coding = '
q'
then
begin
coderclass := IdCoderQuotedPrintable.TIdDecoderQuotedPrintable;
if AIsHeader
then
encoded_text := encoded_text.Replace( '
_', '
' );
end else if coding = '
b'
then
begin
coderclass := IdCoderMIME.TIdDecoderMIME;
end
else begin
Exit( false );
end;
decoded_text := coderclass.DecodeString( encoded_text, encoding );
Result := True;
end;
var
idx: Integer;
sp, ep: Integer;
str:
string;
begin
idx := 0;
Result := AStr;
while True
do
begin
sp := Result.IndexOf( '
=?', idx );
if sp < 0
then
break;
ep := Result.IndexOf( '
?=', sp + 2 );
if ep < 0
then
break;
if TryDecode( Result.Substring( sp + 2, ep - ( sp + 2 ) ), str )
then
Result := Result.Substring( 0, sp ) + str + Result.Substring( ep + 2 )
else
idx := ep + 2;
end;
end;
begin
try
Writeln( Decode( '
Subject: =?iso-8859-1?q?this=20is=20some=20text?= =?UTF-8?Q?Planm=C3=A4=C3=9Fige_Erh=C3=B6hung_xx-xx-xx?=', True ) );
except
on E:
Exception do
Writeln( E.ClassName, '
: ', E.
Message );
end;
Readln;
end.