'=========================================
LOCAL FN DecodeBase64(hndl&)
DIM osErr%
DIM result&,state%,size&,rsize&
DIM ofs&,s%,rep%
DIM rPtr&,i&,j%,r&;0,rh%,rl%,p%
DEFSTR LONG
result& = _nil
LONG IF hndl&<>_nil
state% = FN HGETSTATE(hndl&)
osErr% = FN HUNLOCK(hndl&)
s% = &H0D00 : ofs& = 0 : rep% = 0
DO
ofs& = FN MUNGER (hndl&,ofs&,@s%,1,@rep%,0)
UNTIL ofs&<0
s% = &H0A00 : ofs& = 0
DO
ofs& = FN MUNGER (hndl&,ofs&,@s%,1,@rep%,0)
UNTIL ofs&<0
size& = FN GETHANDLESIZE(hndl&)
LONG IF size&<>0 AND (size& AND 3<>0)
rsize& = (size&>>2)*3
result& = FN NEWHANDLE (rsize&)
LONG IF result&<>_nil
osErr% = FN HLOCK(hndl&)
osErr% = FN HLOCK(result&)
rPtr& = [result&]
FOR i&=0 TO size&-1 STEP 4
r& = 0
FOR j%=0 TO 3
p% = PEEK([hndl&]+i&+j%)
COMPILE LONG IF _false
SELECT
CASE p%>=_"A" AND p%<=_"Z"
p% = p%-&H41
CASE p%>=_"a" AND p%<=_"z"
p% = p%-&H47
CASE p%>=_"0" AND p%<=_"9"
p% = p%+&H04
CASE p%=_"+"
p% = p%+&H13
CASE p%=_"/"
p% = p%+&H10
CASE ELSE
p% = 0
END SELECT
COMPILE END IF
SELECT
CASE p%>=_"a"
p% = p%-&H47
CASE p%>=_"A"
p% = p%-&H41
CASE p%>=_"0" AND p%<=_"9"
p% = p%+&H04
CASE p%=_"+"
p% = p%+&H13
CASE p%=_"/"
p% = p%+&H10
CASE ELSE
p% = 0
END SELECT
'p% =
INSTR(1,"BCDEFGHIJKLMNOPQRSTUVEXYZabcdefghijklmnopqrstuvwxyz0123456789+/",CH
R$(p%))
' You had better user table for better performance.
r& = (r&<<6)+p%
NEXT j%
POKE rPtr& ,rh%
% rPtr&+1,rl%
rPtr& = rPtr&+3
NEXT
osErr% = FN HUNLOCK(result&)
LONG IF {([hndl&]+size&-2)}=_"=="
osErr% = FN SETHANDLESIZE(result&,rsize&-2)
XELSE
LONG IF PEEK([hndl&]+size&-1)=_"="
osErr% = FN SETHANDLESIZE(result&,rsize&-1)
END IF
END IF
END IF
END IF
osErr% = FN HSETSTATE(hndl&,state%)
END IF
END FN = result&