1

我目前正在将目前不支持 Unicode 的 PowerBuilder 12.1 应用程序转换为支持 Unicode 的应用程序。

我进行了一些修改以将 Unicode 数据保存到我们的数据库以及文件中,但是在处理字符串时遇到了一些小问题。

例如,字符是代理对,PowerBuilder 将其解释为 2 个字符(类似于 .NET 的操作方式)。因此:

LEN("") = 2

对我来说,这部分很有意义,因为它将每个代码单元都算作一个字符。

目前我们已经提出了两种解决方案来处理使用 Unicode 字符的字符串函数:

  • 用 C# .NET 编写的可调用 OLEObjects
  • 使用 PBNI 接口调用 C# .NET(如果可能,希望远离此解决方案

我们正在考虑用于确定字符串长度的 .NET 代码示例是:

StringInfo.ParseCombiningCharacters("").Length = 1

我们只是担心不断调用 OLEObjects/PBNI 来完成我们所有的字符串处理对性能的影响。这里有没有其他 PowerBuilder 开发人员做过 Unicode 字符串操作(LEN、MID、POS 等),你是怎么做的?

谢谢你。

4

3 回答 3

1

自 10 版以来,PB 支持 unicode (utf-16le)。所以遗留Len()是隐式的LenW()(与其他字符串函数一样,处理遗留数据可能意味着使用显式LenA())。

你确定你得到了一些 utf-16le 编码吗?给定以下函数,如果您使用 调用它,它会在包含您的数据的字符串上返回什么hexdump_blob(blob(your_string))

将此代码粘贴到名为hexdump_blob具有十六进制显示(类似于十六进制编辑器)的 blob 内容的新全局函数的源代码中。

global type hexdump_blob from function_object
end type

forward prototypes
global function string hexdump_blob (blob abl_data, boolean ab_fill_lastline)
end prototypes

global function string hexdump_blob (blob abl_data, boolean ab_fill_lastline);//hexify a blob content
string ls_tohex = "0123456789ABCDEF"
string ls_msg = "", ls_line, ls_binary
long i, j, length
byte b
string ls_fill

if isnull( abl_data ) then return ""

if ab_fill_lastline then
    ls_fill = " __"
else
    ls_fill = "   "
end if

length = len( abl_data )
for i = 1 to length
    GetByte( abl_data, i, b )
    ls_line += mid( ls_tohex, 1+ mod(int(b/16),16), 1)
    ls_line += mid( ls_tohex, 1+ mod(b,16), 1)
    ls_line += " "
    ls_binary += string( iif(b>31 and b<128,char(b)," "))
    if mod(i,16) = 0 and i > 0 then
        ls_binary = replaceall( ls_binary, "~r", "·")   //no cr/lf
        ls_binary = replaceall( ls_binary, "~n", "·")
        ls_binary = replaceall( ls_binary, "~t", "·")
        ls_msg += "[" + string( i - 16, "0000") + "] " + ls_line + "~t" + ls_binary + "~r~n"
        ls_line = ""
        ls_binary = ""
    end if
next
i -- // i - 1 due to the last loop in for
ls_line += fill(ls_fill, 3 * ( 16 - mod(i, 16) ) )
ls_msg += "[" + string( i - mod(i,16), "0000") + "] " + ls_line + "~t" + ls_binary

return ls_msg

end function

此外,这是replaceall()使用的功能hexdump_blob()

global type replaceall from function_object
end type

forward prototypes
global function string replaceall (string as_source, string as_pattern, string as_replace)
end prototypes

global function string replaceall (string as_source, string as_pattern, string as_replace);//remplace toute les occurences de as_pattern de as_source par as_replace 
string ls_target
long i, j

ls_target=""
i = 1
j = 1
do
    i = pos( as_source, as_pattern, j )
    if i>0 then
        ls_target += mid( as_source, j, i - j )
        ls_target += as_replace
        j = i + len( as_pattern )
    else
        ls_target += mid( as_source, j )
    end if
loop while i>0

return ls_target
end function

以及iif()模拟 C 三元运算符或 Visual Basic iif() 的

global type iif from function_object
end type

forward prototypes
global function any iif (boolean ab_cond, any aa_true, any aa_false)
end prototypes

global function any iif (boolean ab_cond, any aa_true, any aa_false);
// simulates the VB iif or C ternary operator

if ab_cond then
    return aa_true
else
    return aa_false
end if

end function
于 2012-10-03T07:58:51.683 回答
1

这是为了响应 Seki 的十六进制转换功能。我将其发布为答案,以便我可以包含源代码。我使用 Microsoft 加密函数在我的调试工具中显示 blob。这是我的 blob 窗口的简化版本。我使用的是基于 PFC 的,并且使用了一个包装了 MS Crypto 库的对象。它来自 PB 12.5,但应该导入任何 Unicode 版本的 PB。

HA$PBExportHeader$w_show_blob.srw
forward
global type w_show_blob from window
end type
type sle_1 from singlelineedit within w_show_blob
end type
type mle_1 from multilineedit within w_show_blob
end type
end forward

global type w_show_blob from window
integer width = 3081
integer height = 1988
boolean titlebar = true
boolean controlmenu = true
boolean minbox = true
boolean maxbox = true
boolean resizable = true
boolean center = true
sle_1 sle_1
mle_1 mle_1
end type
global w_show_blob w_show_blob

type prototypes
FUNCTION boolean CryptBinaryToString ( &
    Blob pbBinary, &
    ulong cbBinary, &
    ulong dwFlags, &
    Ref string pszString, &
    Ref ulong pcchString ) &
LIBRARY "crypt32.dll" ALIAS FOR "CryptBinaryToStringW"

end prototypes

type variables
CONSTANT Ulong CRYPT_STRING_HEXASCIIADDR = 11   

end variables

forward prototypes
public subroutine of_showblob (ref blob abl_data)
end prototypes

public subroutine of_showblob (ref blob abl_data);unsignedlong lul_size, lul_bufsize
string ls_hex
try
    lul_size = len(abl_data)
    sle_1.text = string(lul_size)


    setnull(ls_hex)
    cryptbinarytostring( abl_data, lul_size, CRYPT_STRING_HEXASCIIADDR, ls_hex, lul_bufsize)
    ls_hex = space(lul_bufsize)
    if not cryptbinarytostring( abl_data, lul_size, CRYPT_STRING_HEXASCIIADDR , ls_hex, lul_bufsize) then
        mle_1.text = "error converting blob data"
    else
        mle_1.text = ls_hex
    end if
catch(runtimeerror re)
    messagebox("oops", re.text)


end try


end subroutine

on w_show_blob.create
this.sle_1=create sle_1
this.mle_1=create mle_1
this.Control[]={this.sle_1,&
this.mle_1}
end on

on w_show_blob.destroy
destroy(this.sle_1)
destroy(this.mle_1)
end on

type sle_1 from singlelineedit within w_show_blob
integer x = 73
integer width = 517
integer height = 88
integer taborder = 10
integer textsize = -10
integer weight = 400
fontcharset fontcharset = ansi!
fontpitch fontpitch = variable!
fontfamily fontfamily = swiss!
string facename = "Arial"
long textcolor = 33554432
long backcolor = 553648127
string text = "none"
boolean displayonly = true
borderstyle borderstyle = stylelowered!
end type

type mle_1 from multilineedit within w_show_blob
integer x = 64
integer y = 96
integer width = 2898
integer height = 1716
integer taborder = 10
integer textsize = -10
integer weight = 400
fontcharset fontcharset = ansi!
fontpitch fontpitch = fixed!
fontfamily fontfamily = modern!
string facename = "Courier New"
long textcolor = 33554432
string text = "none"
boolean hscrollbar = true
boolean vscrollbar = true
boolean displayonly = true
borderstyle borderstyle = stylelowered!
end type

要使用它,假设您的 blob 是 lbl_myBlob:

open(w_show_blob)
w_show_blob.of_showblob(lbl_myBlob)

MLE 中的输出如下所示:

0000    42 4d ee 00 00 00 00 00  00 00 76 00 00 00 28 00   BM........v...(.
0010    00 00 10 00 00 00 0f 00  00 00 01 00 04 00 00 00   ................
0020    00 00 78 00 00 00 00 00  00 00 00 00 00 00 00 00   ..x.............
0030    00 00 00 00 00 00 00 00  00 00 00 00 80 00 00 80   ................
0040    00 00 00 80 80 00 80 00  00 00 80 00 80 00 80 80   ................
0050    00 00 80 80 80 00 c0 c0  c0 00 00 00 ff 00 00 ff   ................
0060    00 00 00 ff ff 00 ff 00  00 00 ff 00 ff 00 ff ff   ................
0070    00 00 ff ff ff 00 88 88  88 88 88 88 88 88 88 88   ................
0080    80 88 88 88 88 88 88 88  80 08 88 88 88 88 88 88   ................
0090    80 00 88 88 88 88 88 88  80 00 08 88 88 88 88 88   ................
00a0    80 00 00 88 88 88 88 88  80 00 00 08 88 88 88 88   ................
00b0    80 00 00 00 88 88 88 88  80 00 00 08 88 88 88 88   ................
00c0    80 00 00 88 88 88 88 88  80 00 08 88 88 88 88 88   ................
00d0    80 00 88 88 88 88 88 88  80 08 88 88 88 88 88 88   ................
00e0    80 88 88 88 88 88 88 88  88 88 88 88 88 88         ..............
于 2012-11-15T01:41:59.297 回答