RosettaCodeData/Task/Variable-length-quantity/Phix/variable-length-quantity.phix

45 lines
1.1 KiB
Plaintext

function vlq_encode(sequence s)
sequence res = {}
integer n, msb
for i=length(s) to 1 by -1 do
n = s[i]
if n<0 then crash("unsigned integers only!") end if
msb = 0
while 1 do
res = prepend(res,msb+and_bits(n,#7F))
n = floor(n/#80)
if n=0 then exit end if
msb = #80
end while
end for
return res
end function
function vlq_decode(sequence s)
sequence res = {}
integer n = 0, byte
for i=1 to length(s) do
byte = s[i]
n = n*#80+and_bits(byte,#7F)
if not and_bits(byte,#80) then
res = append(res,n)
n = 0
end if
end for
return res
end function
function svlg(sequence s)
string res = ""
for i=1 to length(s) do
res &= sprintf("#%02x:",{s[i]})
end for
return res[1..$-1]
end function
constant testNumbers = { #200000, #1FFFFF, 1, 127, 128 }
sequence s = vlq_encode(testNumbers)
sequence decoded = vlq_decode(s)
printf(1,"%s -> %s -> %s\n",{svlg(testNumbers),svlg(s),svlg(decoded)})
if decoded!=testNumbers then crash("something wrong") end if