1

現在、UnicodeをサポートしていないPowerBuilder12.1アプリケーションをUnicodeをサポートするアプリケーションに変換する作業を行っています。

Unicodeデータをデータベースとファイルに保存するためにいくつかの変更を加えましたが、文字列の処理にわずかな問題が発生しました。

たとえば、文字はサロゲートペアであり、PowerBuilderはこれを2文字として解釈します(.NETの動作と同様)。したがって:

LEN("") = 2

私にとって、この部分は、各コード単位を文字として数えるので、理にかなっています。

現在、Unicode文字を使用した文字列関数の実行を処理するための2つのソリューションを考え出しました。

  • 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コンテンツの16進表示(16進エディターのような)を持つように指定された新しいグローバル関数のソースコードに貼り付けます。

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三項演算子、またはビジュアルベーシック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 の 16 進変換機能への対応です。ソースコードを含めることができるように、回答として投稿しています。Microsoft の暗号化機能を使用して、デバッグ ツールで BLOB を表示しています。これは、私のブロブ ウィンドウの簡略化されたバージョンです。私が使用するのは PFC ベースで、MS Crypto ライブラリをラップするオブジェクトを使用します。これは PB 12.5 のものですが、PB の任意の Unicode バージョンにインポートする必要があります。

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

これを使用するには、ブロブが 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 に答える