1

Resolved

New function for url encoding

description

Please add a function for URL Encoding e.g. in string service.

A possible solution (bug in of_decimal functions in numerical Service have to fixed too):
string ls_return, ls_bin
char lc_char
long ll_i, ll_len
n_cst_numerical lnv_numerical


IF IsNull (as_value) THEN return ""

ll_len = Len (as_value)
FOR ll_i = 1 TO ll_len
    lc_char = Mid (as_value, ll_i, 1)
    IF (ASC ('A') <= ASC (lc_char) AND ASC (lc_char) <= ASC ('Z')) THEN     // 'A'..'Z'
        ls_return += string (lc_char)
        
    ELSEIF (ASC ('a') <= ASC (lc_char) AND ASC (lc_char) <= ASC ('z')) THEN // 'a'..'z'
        ls_return += string (lc_char)
        
    ELSEIF (ASC ('0') <= ASC (lc_char) AND ASC (lc_char) <= ASC ('9')) THEN // '0'..'9'
        ls_return += string (lc_char)
        
    ELSEIF (lc_char = ' ') THEN                         // space
        ls_return += "+"
        
    ELSEIF (lc_char = '-' OR lc_char = '_'  OR &        
                lc_char = '.' OR lc_char = '!' OR &
                lc_char = '~~' OR lc_char = '*' OR &
                lc_char = "'" OR lc_char = '(' OR &
                lc_char = ')') THEN                             // unreserved
        ls_return += string (lc_char)
        
    ELSEIF (ASC (lc_char) <= 127) THEN                  // other ASCII
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (ASC (lc_char)), 2)
        
    ELSEIF (ASC (lc_char) <= 2047) THEN                 // non-ASCII <= 0x7FF
        // 0xc0 | (lc_char >> 6)
        ls_bin = "000000" + lnv_numerical.of_binary (ASC (lc_char))
        ls_bin = Left (ls_bin, Len (ls_bin) - 6)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (192, lnv_numerical.of_decimal(ls_bin))), 2)
        
        // 0x80 | (lc_char & 0x3F)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (128, lnv_numerical.of_bitwiseand (ASC (lc_char), 63))), 2)
        
    ELSE                                                            // 0x7FF < lc_char <= 0xFFFF
        // 0xe0 | (lc_char >> 12)
        ls_bin = "000000000000" + lnv_numerical.of_binary (ASC (lc_char))
        ls_bin = Left (ls_bin, Len (ls_bin) - 12)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (224, lnv_numerical.of_decimal(ls_bin))), 2)
        
        // 0x80 | ((lc_char >> 6) & 0x3F)
        ls_bin = "000000" + lnv_numerical.of_binary (ASC (lc_char))
        ls_bin = Left (ls_bin, Len (ls_bin) - 6)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (128, lnv_numerical.of_bitwiseand (lnv_numerical.of_decimal(ls_bin), 63))), 2)
        
        // 0x80 | (lc_char & 0x3F)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (128, lnv_numerical.of_bitwiseand (ASC (lc_char), 63))), 2)
    END IF
NEXT

return ls_return

comments

TAB_Ullrich wrote Dec 12, 2014 at 8:27 AM

Here is an optimization of the code (faster bit shifting):
string ls_return
char lc_char
long ll_i, ll_len
n_cst_numerical lnv_numerical


IF IsNull (as_value) THEN return ""

ll_len = Len (as_value)
FOR ll_i = 1 TO ll_len
    lc_char = Mid (as_value, ll_i, 1)
    IF (ASC ('A') <= ASC (lc_char) AND ASC (lc_char) <= ASC ('Z')) THEN     // 'A'..'Z'
        ls_return += string (lc_char)
        
    ELSEIF (ASC ('a') <= ASC (lc_char) AND ASC (lc_char) <= ASC ('z')) THEN // 'a'..'z'
        ls_return += string (lc_char)
        
    ELSEIF (ASC ('0') <= ASC (lc_char) AND ASC (lc_char) <= ASC ('9')) THEN // '0'..'9'
        ls_return += string (lc_char)
        
    ELSEIF (lc_char = ' ') THEN                         // space
        ls_return += "+"
        
    ELSEIF (lc_char = '-' OR lc_char = '_'  OR &        
                lc_char = '.' OR lc_char = '!' OR &
                lc_char = '~~' OR lc_char = '*' OR &
                lc_char = "'" OR lc_char = '(' OR &
                lc_char = ')') THEN                             // unreserved
        ls_return += string (lc_char)
        
    ELSEIF (ASC (lc_char) <= 127) THEN                  // other ASCII
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (ASC (lc_char)), 2)
        
    ELSEIF (ASC (lc_char) <= 2047) THEN                 // non-ASCII <= 0x7FF
        // 0xc0 | (lc_char >> 6)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (192, INT (ASC (lc_char) / 2^6))), 2)
        
        // 0x80 | (lc_char & 0x3F)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (128, lnv_numerical.of_bitwiseand (ASC (lc_char), 63))), 2)
        
    ELSE                                                            // 0x7FF < lc_char <= 0xFFFF
        // 0xe0 | (lc_char >> 12)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (224, INT (ASC (lc_char) / 2^12))), 2)
        
        // 0x80 | ((lc_char >> 6) & 0x3F)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (128, lnv_numerical.of_bitwiseand (INT (ASC (lc_char) / 2^6), 63))), 2)
        
        // 0x80 | (lc_char & 0x3F)
        ls_return += "%" + Right ("00" + lnv_numerical.of_hex (lnv_numerical.of_bitwiseor (128, lnv_numerical.of_bitwiseand (ASC (lc_char), 63))), 2)
    END IF
NEXT

return ls_return

TAB_Ullrich wrote Aug 17, 2016 at 8:44 AM

New function of_URLEncode in pfc_n_cst_string.