4

我在 Delphi 2007(不支持 Unicode)中工作,我正在从 Google Analytics API 检索 XML 和 JSON 数据。以下是我为 URL 引用路径获取的一些 UTF-8 编码数据:

ga:referralPath=/add/%D0%9F%D0%B8%D0%B6%D0%B0%D0%BC

当我使用此解码器对其进行解码时,它会正确生成:

ga:referralPath=/add/Пижам

有没有我可以在 Delphi 2007 中使用的函数来执行这个解码?

UPDATE 此数据对应一个 URL。最终我想要做的是将其存储在 SqlServer 数据库中(开箱即用 - 没有修改有关字符集的设置)。然后能够生成/创建一个带有指向该页面的工作链接的 html 页面(注意:在这个示例中,我只处理 url 引用路径 - 显然要制作一个有效的 url 链接需要一个源)。

4

2 回答 2

6

D2007 支持 Unicode,只是没有 D2009+ 支持的程度。D2007 中的 Unicode 是使用WideString少数 RTL 支持函数来处理的。

URL 包含百分比编码的 UTF-8 字节八位字节。只需将这些序列转换为其二进制表示形式,然后用于UTF8Decode()将 UTF-8 数据解码为WideString. 例如:

function HexToBits(C: Char): Byte;
begin
  case C of
    '0'..'9': Result := Byte(Ord(C) - Ord('0'));
    'a'..'f': Result := Byte(10 + (Ord(C) - Ord('a')));
    'A'..'F': Result := Byte(10 + (Ord(C) - Ord('A')));
  else
    raise Exception.Create('Invalid encoding detected');
  end;
end;

var
  sURL: String;
  sWork: UTF8String;
  C: Char;
  B: Byte;
  wDecoded: WideString;
  I: Integer;
begin
  sURL := 'ga:referralPath=/add/%D0%9F%D0%B8%D0%B6%D0%B0%D0%BC';
  sWork := sURL;
  I := 1;
  while I <= Length(sWork) do
  begin
    if sWork[I] = '%' then
    begin
      if (I+2) > Length(sWork) then
        raise Exception.Create('Incomplete encoding detected');
      sWork[I] := Char((HexToBits(sWork[I+1]) shl 4) or HexToBits(sWork[I+2]));
      Delete(sWork, I+1, 2);
    end;
    Inc(I);
  end;
  wDecoded := UTF8Decode(sWork);
  ...
end;
于 2013-01-01T06:54:29.530 回答
1

您可以使用以下代码,该代码使用 Windows API:

function Utf8ToStr(const Source : string) : string;
var
  i, len : integer;
  TmpBuf : array of byte;
begin
  SetLength(Result, 0);
  i := MultiByteToWideChar(CP_UTF8, 0, @Source[1], Length(Source), nil, 0);
  if i = 0 then Exit;
  SetLength(TmpBuf, i * SizeOf(WCHAR));
  Len := MultiByteToWideChar(CP_UTF8, 0, @Source[1], Length(Source), @TmpBuf[0], i);
  if Len = 0 then Exit;

  i := WideCharToMultiByte(CP_ACP, 0, @TmpBuf[0], Len, nil, 0, nil, nil);
  if i = 0 then Exit;

  SetLength(Result, i);
  i := WideCharToMultiByte(CP_ACP, 0, @TmpBuf[0], Len, @Result[1], i, nil, nil);
  SetLength(Result, i);
end;
于 2013-01-01T09:19:27.850 回答