RosettaCodeData/Task/Variable-length-quantity/Cowgol/variable-length-quantity.cowgol
2023-07-01 13:44:08 -04:00

63 lines
1.2 KiB
Text

include "cowgol.coh";
sub VLQEncode(number: uint32, buf: [uint8]) is
var step := number;
while step > 0 loop
step := step >> 7;
buf := @next buf;
end loop;
var mark: uint8 := 0;
while number > 0 loop
buf := @prev buf;
[buf] := mark | (number as uint8 & 0x7F);
mark := 0x80;
number := number >> 7;
end loop;
end sub;
sub VLQDecode(buf: [uint8]): (result: uint32) is
result := 0;
loop
var byte := [buf];
buf := @next buf;
result := (result << 7) | (byte & 0x7F) as uint32;
if byte & 0x80 == 0 then
return;
end if;
end loop;
end sub;
sub VLQPrint(buf: [uint8]) is
loop
print_hex_i8([buf]);
if [buf] & 0x80 == 0 then
break;
end if;
buf := @next buf;
end loop;
end sub;
sub VLQTest(value: uint32) is
var buf: uint8[8];
print("Input: ");
print_hex_i32(value);
print_nl();
print("Encoded: ");
VLQEncode(value, &buf[0]);
VLQPrint(&buf[0]);
print_nl();
print("Decoded: ");
value := VLQDecode(&buf[0]);
print_hex_i32(value);
print_nl();
end sub;
VLQTest(0x200000);
print_nl();
VLQTest(0x1FFFFF);
print_nl();