Utf8ToString和旧的Delphi版本

时间:2011-09-22 17:22:47

标签: delphi

我想在旧版和新版Delphi中使用某些单元。从最近的Delphi版本开始,Utf8Decode抛出一个已弃用的警告,建议切换到Utf8ToString。问题是旧版本的Delphi没有声明这个函数,所以我应该使用哪个{$IFDEF}标签来定义名为Utf8Decode {或者Utf8String的{​​{1}}的包装器?

或换句话说:Utf8ToWideString引入了哪个版本?

2 个答案:

答案 0 :(得分:6)

我想我会用$IF来实现它,这样调用代码就可以使用新的RTL函数,或者使用旧的弃用版本。由于新的UTF8ToString返回一个UnicodeString,我认为可以安全地假设它是在Delphi 2009中引入的。

{$IF not Declared(UTF8ToString)}
function UTF8ToString(const s: UTF8String): WideString;
begin
  Result := UTF8Decode(s);
end;
{$IFEND}

答案 1 :(得分:2)

据我记得:

    在Delphi 6中引入了
  • UTF8String和相关的UTF8Encode / UTF8Decode;
  • UTF8ToWideStringUTF8ToString在Delphi 2009(即Unicode版本)中引入,如下:

    function UTF8Decode(const S: RawByteString): WideString; 
       deprecated 'Use UTF8ToWideString or UTF8ToString';
    

为了解决此兼容性问题,您可以定义自己的UTF8ToString函数(如David建议的那样),也可以使用自己的实现。

我为我们的框架改写了一些(也许)更快的版本,它也适用于Delphi 5(我想为一些传统的Delphi 5代码添加UTF-8支持,大约3,000,000个带有第三方组件的源代码行停止轻松升级 - 至少是经理的决定)。查看SynCommons.pas中的所有相应RawUTF8类型:

{$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}