使用PowerBuilder 12.1处理Unicode字符串操作的函数

时间:2012-10-02 16:14:15

标签: unicode powerbuilder

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

我已经做了一些修改以将Unicode数据保存到我们的数据库以及文件中,但是我在处理字符串方面遇到了一些麻烦。

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

LEN("") = 2

对我而言,这部分是有道理的,因为它将每个代码单元计为一个字符。

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

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

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

StringInfo.ParseCombiningCharacters("").Length = 1

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

谢谢。

3 个答案:

答案 0 :(得分: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

和模拟C三元运算符的iif(),或者是基本的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

答案 1 :(得分: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         ..............

答案 2 :(得分:0)