Implement some operations on variable-length quantities, at least including conversions from a normal number in the language to the binary representation of the variable-length quantity for that number, and vice versa. Any variants are acceptable.



Task

With above operations,

convert these two numbers 0x200000 (2097152 in decimal) and 0x1fffff (2097151 in decimal) into sequences of octets (an eight-bit byte); 
display these sequences of octets;
convert these sequences of octets back to numbers, and check that they are equal to original numbers.


$ include "seed7_05.s7i";
  include "bigint.s7i";
 
const func string: toSequence (in var bigInteger: number) is func
  result
    var string: sequence is "";
  begin
    sequence := str(chr(ord(number mod 128_)));
    number >>:= 7;
    while number <> 0_ do
      sequence := str(chr(ord(number mod 128_) + 128)) & sequence;
      number >>:= 7;
    end while;
  end func;
 
const func bigInteger: fromSequence (in string: sequence) is func
  result
    var bigInteger: number is 0_;
  local
    var integer: index is 1;
  begin
    while ord(sequence[index]) >= 128 do
      number <<:= 7;
      number +:= bigInteger conv (ord(sequence[index]) - 128);
      incr(index);
    end while;
    number <<:= 7;
    number +:= bigInteger conv ord(sequence[index]);
  end func;
 
const proc: main is func
  local
    const array bigInteger: testValues is [] (
        0_, 10_, 123_, 254_, 255_, 256_, 257_, 65534_, 65535_, 65536_, 65537_, 2097151_, 2097152_);
    var string: sequence is "";
    var bigInteger: testValue is 0_;
    var char: element is ' ';
  begin
    for testValue range testValues do
      sequence := toSequence(testValue);
      write("sequence from " <& testValue <& ": [ ");
      for element range sequence do
        write(ord(element) radix 16 lpad0 2 <& " ");
      end for;
      writeln("] back: " <& fromSequence(sequence));
    end for;
  end func;