2012-10-02 283 views
1

我目前正致力於將我們目前不支持Unicode的PowerBuilder 12.1應用程序轉換爲Unicode支持應用程序。使用PowerBuilder處理Unicode字符串操作的函數12.1

我已經做了一些修改,將Unicode數據保存到我們的數據庫以及文件中,但是在處理字符串時遇到了一些問題。

例如,角色是代理對,PowerBuilder將其解釋爲2個字符(類似於.NET的運行方式)。因此:

LEN("") = 2 

對我來說,這部分是有意義的,因爲它將每個代碼單元計爲一個字符。

目前,我們已經提出了兩種解決方案來處理這樣字符串函數與Unicode字符:寫在C#.NET

  • 使用PBNI接口來調用C#.NET

    • 可贖回OLEObjects(希望從該溶液中如果可能

    我們正在考慮使用用於確定字符串長度的.NET代碼的一個例子遠離是:

    StringInfo.ParseCombiningCharacters("").Length = 1 
    

    我們只是擔心對性能的影響,不斷調用OLEObjects/PBNI來完成我們所有的字符串處理。有沒有其他的PowerBuilder開發人員在這裏完成Unicode字符串操作(LEN,MID,POS等),以及你是如何做到的?

    謝謝。

  • 回答

    0
    +0

    因爲'莉娜()'是ANSI文本,我想這個OP不會有不同的結果。 – Seki

    +0

    是的,不幸的是,LenA()不能用於我們正在尋找的東西。我們試圖用總視覺字符來計數,而不是用代碼單元來計算。 –

    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 = "ABCDEF" 
    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

    這是爲了響應Seki的十六進制轉換功能。我將它發佈爲答案,以便我可以包含源代碼。我使用Microsoft加密函數在我的調試工具中顯示斑點。這是我的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 
    

    要使用它,假設你的斑點是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   ..............