I want to use some units in both older and newer versions of Delphi. 开发者_Python百科Since a recent Delphi version, Utf8Decode
throws a deprecated warning which advises to switch to Utf8ToString
. Problem is older versions of Delphi don't declare this function, so which {$IFDEF}
label should I use to define a wrapper around Utf8Decode
named Utf8String
(or perhaps Utf8ToWideString
)?
Or in other words: which version was Utf8ToString
introduced?
I think I would implement it with an $IF
so that calling code can use either the new RTL function, or fall back on the older deprecated version. Since the new UTF8ToString
returns a UnicodeString I think it is safe to assume that it was introduced in Delphi 2009.
{$IF not Declared(UTF8ToString)}
function UTF8ToString(const s: UTF8String): WideString;
begin
Result := UTF8Decode(s);
end;
{$IFEND}
As far as I remember:
UTF8String
and associatedUTF8Encode / UTF8Decode
were introduced in Delphi 6;UTF8ToWideString
andUTF8ToString
were introduced in Delphi 2009 (i.e. Unicode version), as such:function UTF8Decode(const S: RawByteString): WideString; deprecated 'Use UTF8ToWideString or UTF8ToString';
In order to get rid of this compatibility issue, you can either define your own UTF8ToString
function (as David propose), or either use your own implementation.
I rewrote some (perhaps) faster version for our framework, which works also with Delphi 5 (I wanted to add UTF-8 support for some legacy Delphi 5 code, some 3,000,000 source code lines with third party components which stops easy upgrade - at least for the manager's decision). See all corresponding RawUTF8
type in SynCommons.pas:
{$ifdef UNICODE}
function UTF8DecodeToString(P: PUTF8Char; L: integer): string;
begin
result := UTF8DecodeToUnicodeString(P,L);
end;
{$else}
function UTF8DecodeToString(P: PUTF8Char; L: integer): string;
var Dest: RawUnicode;
begin
if GetACP=CODEPAGE_US then begin
if (P=nil) or (L=0) then
result := '' else begin
SetLength(Dest,L); // faster than Windows API / Delphi RTL
SetString(result,PAnsiChar(pointer(Dest)),UTF8ToWinPChar(pointer(Dest),P,L));
end;
exit;
end;
result := '';
if (P=nil) or (L=0) then
exit;
SetLength(Dest,L*2);
L := UTF8ToWideChar(pointer(Dest),P,L) shr 1;
SetLength(result,WideCharToMultiByte(GetACP,0,pointer(Dest),L,nil,0,nil,nil));
WideCharToMultiByte(GetACP,0,pointer(Dest),L,pointer(result),length(result),nil,nil);
end;
{$endif}
精彩评论