停止Firebird根据Windows charset修改字符串

时间:2013-02-12 16:18:23

标签: character-encoding firebird firebird1.5 uib

我有一个使用1.5.5 Firebird嵌入式引擎的应用程序(用Delphi编写)。我正在使用此引擎,因为该应用程序适用于当前部署的Firebird数据库,而较新的嵌入式引擎无法正确打开数据库文件(ODS 10.1)。数据库中的所有字符串都定义为VARCHAR(N),其中N变化。该应用程序曾经是ANSI应用程序,因此数据包含ISO-latin-1字符。现在,应用程序已升级为unicode应用程序。为了在现有数据库(大约10k个实例)中存储Unicode字符,我编写了一个UTF8-BOM(如果你可以调用它),然后字符串的其余部分被认为是UTF8并由数据库层解码。这样我们就可以使用所有现有的数据库,仍然使用所有Unicode字符。

这适用于西欧的所有机器。但是当应用程序在罗马尼亚(具有罗马尼亚语言设置的Windows PC)中运行时:数据库引擎会改变字符。例如:UTF8字符串以字符八位字节EF(ï)开头。数据库引擎将其返回为八位字节69(i)。

如何解决现有数据库的问题?

注意:我在打开数据库时尝试指定字符集OCTETS(使用UIB库),但由于字符集未知,因此失败。

发现问题出在UIB(在这种情况下使用的数据库层)中。 UIB以这样一种方式处理csNONE:如果你给它一个按字节顺序的字符串(数据类型为AnsiString),它只需将字节扩展为字,然后通过当前线程代码页将其减少,就可以转换为UnicodeString。由于罗马尼亚没有使用iso-latin-1作为代码页...数据在那里被破坏了。

现在我在UIBLib中更改了以下例程(例如,当给出ansistring且charset为none且请求ansistring参数时 - >根本不进行转换):

  procedure TSQLDA.EncodeStringA(Code: Smallint; Index: Word; const str: AnsiString);
  begin
  {$IFDEF UNICODE}
    if FCharacterSet = csNONE then begin // new
      EncodeStringB( Code, Index, str ); // new
    end else begin                       // new
      EncodeStringB(Code, Index, MBUEncode(UniCodeString(str), CharacterSetCP[FCharacterSet]));
    end;                                 // new
  {$ELSE}
    EncodeStringB(Code, Index, str);
  {$ENDIF}
  end;

现在我需要检查这个行为是否对库是正确的,并给维护者一个补丁。

0 个答案:

没有答案