青蚨 發表於 2020-12-22 10:22:00

Delphi System单元 Utf8ToAnsi、AnsiToUtf8、Utf8Decode、Utf8Encode、Utf8ToUnicode、UnicodeToUtf8 转换

<p><span style="font-size: 16px"><strong>Delphi System单元 Utf8ToAnsi、AnsiToUtf8、Utf8Decode、Utf8Encode、Utf8ToUnicode、UnicodeToUtf8 转换<br></strong></span></p>
<p><span style="font-size: 16px">单元:System</span></p>
<p><span style="font-size: 16px">原型:</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:delphi;gutter:true;"><span style="font-size: 16px">function UnicodeToUtf8(Dest: PChar; MaxDestBytes: Cardinal; Source: PWideChar; SourceChars: Cardinal): Cardinal;
var
i, count: Cardinal;
c: Cardinal;
begin
Result := 0;
if Source = nil then Exit;
count := 0;
i := 0;
if Dest &lt;&gt; nil then
begin
    while (i &lt; SourceChars) and (count &lt; MaxDestBytes) do
    begin
      c := Cardinal(Source);
      Inc(i);
      if c &lt;= $7F then
      begin
      Dest := Char(c);
      Inc(count);
      end
      else if c &gt; $7FF then
      begin
      if count + 3 &gt; MaxDestBytes then
          break;
      Dest := Char($E0 or (c shr 12));
      Dest := Char($80 or ((c shr 6) and $3F));
      Dest := Char($80 or (c and $3F));
      Inc(count,3);
      end
      else //$7F &lt; Source &lt;= $7FF
      begin
      if count + 2 &gt; MaxDestBytes then
          break;
      Dest := Char($C0 or (c shr 6));
      Dest := Char($80 or (c and $3F));
      Inc(count,2);
      end;
    end;
    if count &gt;= MaxDestBytes then count := MaxDestBytes-1;
    Dest := #0;
end
else
begin
    while i &lt; SourceChars do
    begin
      c := Integer(Source);
      Inc(i);
      if c &gt; $7F then
      begin
      if c &gt; $7FF then
          Inc(count);
      Inc(count);
      end;
      Inc(count);
    end;
end;
Result := count+1;// convert zero based index to byte count
end;

function Utf8ToUnicode(Dest: PWideChar; Source: PChar; MaxChars: Integer): Integer;
var
len: Cardinal;
begin
len := 0;
if Source &lt;&gt; nil then
    while Source &lt;&gt; #0 do
      Inc(len);
Result := Utf8ToUnicode(Dest, MaxChars, Source, len);
end;

function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal;
var
i, count: Cardinal;
c: Byte;
wc: Cardinal;
begin
if Source = nil then
begin
    Result := 0;
    Exit;
end;
Result := Cardinal(-1);
count := 0;
i := 0;
if Dest &lt;&gt; nil then
begin
    while (i &lt; SourceBytes) and (count &lt; MaxDestChars) do
    begin
      wc := Cardinal(Source);
      Inc(i);
      if (wc and $80) &lt;&gt; 0 then
      begin
      if i &gt;= SourceBytes then Exit;          // incomplete multibyte char
      wc := wc and $3F;
      if (wc and $20) &lt;&gt; 0 then
      begin
          c := Byte(Source);
          Inc(i);
          if (c and $C0) &lt;&gt; $80 then Exit;      // malformed trail byte or out of range char
          if i &gt;= SourceBytes then Exit;      // incomplete multibyte char
          wc := (wc shl 6) or (c and $3F);
      end;
      c := Byte(Source);
      Inc(i);
      if (c and $C0) &lt;&gt; $80 then Exit;       // malformed trail byte

      Dest := WideChar((wc shl 6) or (c and $3F));
      end
      else
      Dest := WideChar(wc);
      Inc(count);
    end;
    if count &gt;= MaxDestChars then count := MaxDestChars-1;
    Dest := #0;
end
else
begin
    while (i &lt; SourceBytes) do
    begin
      c := Byte(Source);
      Inc(i);
      if (c and $80) &lt;&gt; 0 then
      begin
      if i &gt;= SourceBytes then Exit;          // incomplete multibyte char
      c := c and $3F;
      if (c and $20) &lt;&gt; 0 then
      begin
          c := Byte(Source);
          Inc(i);
          if (c and $C0) &lt;&gt; $80 then Exit;      // malformed trail byte or out of range char
          if i &gt;= SourceBytes then Exit;      // incomplete multibyte char
      end;
      c := Byte(Source);
      Inc(i);
      if (c and $C0) &lt;&gt; $80 then Exit;       // malformed trail byte
      end;
      Inc(count);
    end;
end;
Result := count+1;
end;

function Utf8Encode(const WS: WideString): UTF8String;
var
L: Integer;
Temp: UTF8String;
begin
Result := '';
if WS = '' then Exit;
SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator

L := UnicodeToUtf8(PChar(Temp), Length(Temp)+1, PWideChar(WS), Length(WS));
if L &gt; 0 then
    SetLength(Temp, L-1)
else
    Temp := '';
Result := Temp;
end;

function Utf8Decode(const S: UTF8String): WideString;
var
L: Integer;
Temp: WideString;
begin
Result := '';
if S = '' then Exit;
SetLength(Temp, Length(S));

L := Utf8ToUnicode(PWideChar(Temp), Length(Temp)+1, PChar(S), Length(S));
if L &gt; 0 then
    SetLength(Temp, L-1)
else
    Temp := '';
Result := Temp;
end;

function AnsiToUtf8(const S: string): UTF8String;
begin
Result := Utf8Encode(S);
end;

function Utf8ToAnsi(const S: UTF8String): string;
begin
Result := Utf8Decode(S);
end; </span></pre>
</div>
<p><span style="font-size: 16px">从源码中可以看到&nbsp;</span></p>
<ul>
<li><span style="font-size: 16px">Utf8ToAnsi 调用了 Utf8Decode 函数</span></li>
<li><span style="font-size: 16px">AnsiToUtf8 调用了 Utf8Encode 函数</span></li>
</ul>
<p><span style="font-size: 16px">所以解码的时候用&nbsp;Utf8ToAnsi 或&nbsp;Utf8Decode 都可以的。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: rgba(136, 136, 136, 1)">创建时间:2020.12.22  更新时间:</span></p>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    博客园 滔Roy https://www.cnblogs.com/guorongtao 希望内容对你有所帮助,谢谢!<br><br>
来源:https://www.cnblogs.com/guorongtao/p/14171632.html
頁: [1]
查看完整版本: Delphi System单元 Utf8ToAnsi、AnsiToUtf8、Utf8Decode、Utf8Encode、Utf8ToUnicode、UnicodeToUtf8 转换