Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Pages: 1
Bonjour,
j'avais besoin de pouvoir générer et relire de la Base64 il y a peu dans une appli PB.
Si possible en n'utilisant pas de dépendance externe (comme sous-traiter l'encodage à la base de données).
Je me suis intéressé à l'algo de la Base64 et le résultat est un objet PB autonome (*).
C'est pas un foudre de guerre sur des méga octets de données en PBScript (c'est rien de le dire), mais si vous avez besoin de lire ou écrire de petites quantités (quelques ko - avec quelque < 10) ça passe tout seul.
Ça utilise le type byte, donc c'est pour du PB >= 10.5 (ou alors il va falloir réécrire des trucs)
(*) bon d'accord : en me relisant et en regardant le code, je vois que j'ai utilisé les fonctions bitwiseor() et bitwiseand() de mon extension pbnicw histoire de pas être trop lent dans les calculs. Si vous voulez, il existe des fonctions de calculs et / ou en pur PBscript (je crois chez real's howto) mais alors là, ça va vraiment être une limace
PS: on ne peut pas attacher de fichier sur ce forum ? c'est quoi ce bin's ??
Bon alors in-extenso :
forward global type nv_codec_base64 from nonvisualobject end type end forward global type nv_codec_base64 from nonvisualobject autoinstantiate end type type variables //Base64 Encoder / Decoder //Seki - 2011 private: byte map1[0 to 63] byte map2[0 to 127] string is_lasterror end variables forward prototypes public subroutine init () public function blob decode (string as_input) public function string encode (blob abl_data) public function string getlasterror () public function string decode_to_utf8 (string as_data) public function string encode_in_utf8 (string as_data) end prototypes public subroutine init (); uint i,c // set Map1 i = 0 For c = Asc("A") To Asc("Z") Map1[i] = c; i ++ Next For c = Asc("a") To Asc("z") Map1[i] = c; i++ Next For c = Asc("0") To Asc("9") Map1[i] = c; i++ Next Map1[i] = Asc("+"); i++ Map1[i] = Asc("/"); i++ // set Map2 For i = 0 To 127 Map2[i] = 255 Next For i = 0 To 63 Map2[Map1[i]] = i Next is_lasterror = "" end subroutine public function blob decode (string as_input); // Decodes a byte array from Base64 format. // Parameters // as_input: a Base64 String to be decoded. // Returns: a blob containing the decoded data bytes. long ll_ILen, ll_OLen long ip, op blob lbl_ret byte lb_ibuf[], lb_out[] byte i0, i1, i2, i3, b0, b1, b2, b3, o0, o1, o2 string ls_tmp is_lasterror = "" as_input = righttrim(as_input, true) ll_ILen = len(as_input) if mod(ll_ILen, 4) <> 0 then is_lasterror = "Length of Base64 encoded input string is not a multiple of 4." return lbl_ret end if Do While ll_ILen > 0 If mid(as_input, ll_ILen, 1) <> "=" Then Exit //Do ll_ILen -- Loop ll_OLen = (ll_ILen * 3) / 4 ls_tmp = space(ll_olen) lb_ibuf = GetByteArray(blob(as_input, EncodingANSI!)) lb_out = getbytearray(blobmid(blob(ls_tmp),1,ll_olen)) ip = 1 op = 1 do while ip <= ll_ILen i0 = lb_ibuf[ip]; ip ++ i1 = lb_ibuf[ip]; ip ++ If ip <= ll_ILen Then i2 = lb_ibuf[ip]; ip ++ Else i2 = asc("A") end if If ip <= ll_ILen Then i3 = lb_ibuf[ip]; ip ++ Else i3 = asc("A") end if If i0 > 127 Or i1 > 127 Or i2 > 127 Or i3 > 127 Then is_lasterror = "Illegal character in Base64 encoded data." return lbl_ret end if b0 = Map2[i0] b1 = Map2[i1] b2 = Map2[i2] b3 = Map2[i3] If b0 > 63 Or b1 > 63 Or b2 > 63 Or b3 > 63 Then is_lasterror = "Illegal character in Base64 encoded data." return lbl_ret end if o0 = bitwiseor((b0 * 4), (b1 / 16)) o1 = bitwiseor(bitwiseand(b1, 15) * 16, b2 / 4) o2 = bitwiseor(bitwiseand(b2, 3) * 64, b3) lb_out[op] = o0; op++ if op <= ll_olen then lb_out[op] = o1; op++ if op <= ll_olen then lb_out[op] = o2; op++ loop return blob(lb_out) end function public function string encode (blob abl_data); // Encodes a byte array into Base64 format. // No blanks or line breaks are inserted. // Parameters: // abl_data: a blob containing the data bytes to be encoded. // Returns: a string with the Base64 encoded data. long ll_InLen //input length long ll_ODataLen //output length without padding long ll_OLen //output length including padding long ip, op byte lb_out[] byte i0, i1, i2, o0, o1, o2, o3 string ls_buf is_lasterror = "" ll_InLen = len(abl_data) if ll_InLen = 0 then return "" ll_ODataLen = (ll_InLen * 4 + 2) / 3 ll_OLen = int((ll_InLen + 2) / 3) * 4 ls_buf = space(ll_OLen) //we need only half of the buffer, as the space() returns an utf-16 string lb_out = GetByteArray(blobmid(blob(ls_buf), 1, ll_OLen)) ip = 1 op = 1 Do While ip <= ll_InLen getbyte(abl_data, ip, i0); ip++ If ip <= ll_InLen Then getbyte(abl_data, ip, i1); ip++ Else i1 = 0 end if If ip <= ll_InLen Then getbyte(abl_data, ip, i2); ip++ Else i2 = 0 end if o0 = int(i0 / 4) o1 = bitwiseor(bitwiseand(i0, 3) * 16, int(i1 / 16)) o2 = bitwiseor(bitwiseand(i1, 15) * 4, int(i2 / 64)) o3 = bitwiseand(i2, 63) lb_out[op] = Map1[o0]; op++ lb_out[op] = Map1[o1]; op++ if op <= ll_ODataLen then lb_out[op] = Map1[o2] else lb_out[op] = asc('=') op++ if op <= ll_ODataLen then lb_out[op] = Map1[o3] else lb_out[op] = asc('=') op++ Loop return string(blob(lb_out), EncodingANSI!) end function public function string getlasterror (); return is_lasterror end function public function string decode_to_utf8 (string as_data); return string(decode(as_data), EncodingUTF8!) end function public function string encode_in_utf8 (string as_data); // helper to encode a string converted into utf-8 into base64 // // we save every null byte from the utf-16 encoding // so the resulting base64 is smaller return encode(blob(as_data, EncodingUTF8!)) end function on nv_codec_base64.create call super::create TriggerEvent( this, "constructor" ) end on on nv_codec_base64.destroy TriggerEvent( this, "destructor" ) call super::destroy end on event constructor; init( ) end event
Hors ligne
Merci pour ta contribution !
seki a écrit:
PS: on ne peut pas attacher de fichier sur ce forum ? c'est quoi ce bin's ??
Non, pas directement dans les forums.
En revanche, si tu veux, tu peux m'envoyer des fichiers que je peux placer dans la rubrique Téléchargements du portail.
Hors ligne
Bonjour,
Merci pour ta contribution.
Pour info, tu peux également trouver les méthodes d'encodage/décodage en base 64 en PB natif dans l'objet libre emailsmtp disponible sur le site (http://www.topwizprogramming.com)
Hors ligne
Pages: 1