2011-09-22 151 views
2

我想在Delphi的舊版本和新版本中使用一些單元。自從最近的一個Delphi版本,Utf8Decode拋出一個不建議使用的警告,建議切換到Utf8ToString。問題是Delphi的舊版本不會聲明這個函數,所以我應該使用哪個{$IFDEF}標籤來定義一個名爲Utf8String(或可能是Utf8ToWideString)的圍繞Utf8Decode的包裝?Utf8ToString和舊的Delphi版本

換句話說:哪個版本是Utf8ToString介紹的?

回答

6

我想我會使用$IF來實現它,以便調用代碼可以使用新的RTL函數,也可以使用舊的棄用版本。由於新UTF8ToString返回的UnicodeString我認爲它是安全的假設,它是在2009年德爾福

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

+1的真棒使用if-未申報 –

+0

另一個問題:我將獲得的性能,如果我做到了,就像這樣:' 型 TUtf8DecodeFunc =功能(const S:UTF8String):WideString; var UTF8ToStringX:TUtf8DecodeFunc; 初始化 {$ IF Declared(UTF8ToString)} UTF8ToStringX:= UTF8ToString; {$ ELSE} UTF8ToStringX:= UTF8Decode; {$ IFEND}' –

+1

這不會給你帶來任何你可以衡量的東西 –

2

至於我記得介紹:

  • UTF8String和相關UTF8Encode/UTF8Decode在Delphi 6中引入;
  • UTF8ToWideStringUTF8ToString是在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}