我目前正致力于将目前不支持Unicode的PowerBuilder 12.1应用程序转换为支持Unicode的应用程序。
我已经做了一些修改以将Unicode数据保存到我们的数据库以及文件中,但是我在处理字符串方面遇到了一些麻烦。
例如,该字符是代理对,PowerBuilder将其解释为2个字符(类似于.NET的操作方式)。因此:
LEN("") = 2
对我而言,这部分是有道理的,因为它将每个代码单元计为一个字符。
目前,我们已经提出了两种解决方案来处理使用Unicode字符的字符串函数:
我们考虑用于确定字符串长度的.NET代码示例是:
StringInfo.ParseCombiningCharacters("").Length = 1
我们只是担心对性能的影响,不断调用OLEObjects / PBNI来完成所有的字符串处理。有没有其他任何PowerBuilder开发人员在这里完成Unicode字符串操作(LEN,MID,POS等),你是怎么做到的?
谢谢。
答案 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)