Powerbuilder pour les completement Geeks !

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.

#1 08-07-2011 07:42:03

seki  
0x73656B69
Award: bf
Lieu: Laquenexy & Luxembourg
Date d'inscription: 20-11-2008
Messages: 1118
Pépites: 4,296,080,204
Banque: 9,223,372,036,854,776,000
Site web

[SOURCE] Encoder / décoder de la Base64 en PB

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 :

Code: pb

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

The best programs are the ones written when the programmer is supposed to be working on something else. - Melinda Varian

Mes réponses PB sur StackOverflow
http://stackoverflow.com/users/flair/317266.png

Hors ligne

 

#2 08-07-2011 07:58:12

erasorz  
Admin
Lieu: Babylone
Date d'inscription: 23-11-2006
Messages: 5121
Pépites: 97,197
Banque: 2,147,483,647

Re: [SOURCE] Encoder / décoder de la Base64 en PB

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.


N'envoyez jamais un humain faire le travail d'un programme.

Hors ligne

 

#3 08-07-2011 08:01:14

buck  
Modérateur
Lieu: Dijon
Date d'inscription: 31-07-2008
Messages: 747
Pépites: 1,028,843
Banque: 171,170,849,654

Re: [SOURCE] Encoder / décoder de la Base64 en PB

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

 

Pied de page des forums

Propulsé par FluxBB 1.2.22