A variable-length unsigned integer using base128 encoding. 1-byte groups consist of 1-bit flag of continuation and 7-bit value chunk, and are ordered "most significant group first", i.e. in "big-endian" manner.
This particular encoding is specified and used in:
More information on this encoding is available at https://en.wikipedia.org/wiki/Variable-length_quantity
This particular implementation supports serialized values to up 8 bytes long.
This page hosts a formal specification of Variable length quantity, unsigned integer, base128, big-endian using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.
import "github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
/**
* A variable-length unsigned integer using base128 encoding. 1-byte groups
* consist of 1-bit flag of continuation and 7-bit value chunk, and are ordered
* "most significant group first", i.e. in "big-endian" manner.
*
* This particular encoding is specified and used in:
*
* * Standard MIDI file format
* * ASN.1 BER encoding
* * RAR 5.0 file format
*
* More information on this encoding is available at
* <https://en.wikipedia.org/wiki/Variable-length_quantity>
*
* This particular implementation supports serialized values to up 8 bytes long.
*/
type VlqBase128Be struct {
Groups []*VlqBase128Be_Group
_io *kaitai.Stream
_root *VlqBase128Be
_parent kaitai.Struct
_f_last bool
last int
_f_value bool
value uint64
}
func NewVlqBase128Be() *VlqBase128Be {
return &VlqBase128Be{
}
}
func (this VlqBase128Be) IO_() *kaitai.Stream {
return this._io
}
func (this *VlqBase128Be) Read(io *kaitai.Stream, parent kaitai.Struct, root *VlqBase128Be) (err error) {
this._io = io
this._parent = parent
this._root = root
for i := 1;; i++ {
tmp1 := NewVlqBase128Be_Group()
err = tmp1.Read(this._io, this, this._root)
if err != nil {
return err
}
_it := tmp1
this.Groups = append(this.Groups, _it)
if !(_it.HasNext) {
break
}
}
return err
}
func (this *VlqBase128Be) Last() (v int, err error) {
if (this._f_last) {
return this.last, nil
}
this._f_last = true
this.last = int(len(this.Groups) - 1)
return this.last, nil
}
/**
* Resulting value as normal integer
*/
func (this *VlqBase128Be) Value() (v uint64, err error) {
if (this._f_value) {
return this.value, nil
}
this._f_value = true
tmp2, err := this.Last()
if err != nil {
return 0, err
}
var tmp3 int;
tmp4, err := this.Last()
if err != nil {
return 0, err
}
if (tmp4 >= 1) {
tmp5, err := this.Last()
if err != nil {
return 0, err
}
tmp3 = this.Groups[tmp5 - 1].Value << 7
} else {
tmp3 = 0
}
var tmp6 int;
tmp7, err := this.Last()
if err != nil {
return 0, err
}
if (tmp7 >= 2) {
tmp8, err := this.Last()
if err != nil {
return 0, err
}
tmp6 = this.Groups[tmp8 - 2].Value << 14
} else {
tmp6 = 0
}
var tmp9 int;
tmp10, err := this.Last()
if err != nil {
return 0, err
}
if (tmp10 >= 3) {
tmp11, err := this.Last()
if err != nil {
return 0, err
}
tmp9 = this.Groups[tmp11 - 3].Value << 21
} else {
tmp9 = 0
}
var tmp12 int;
tmp13, err := this.Last()
if err != nil {
return 0, err
}
if (tmp13 >= 4) {
tmp14, err := this.Last()
if err != nil {
return 0, err
}
tmp12 = this.Groups[tmp14 - 4].Value << 28
} else {
tmp12 = 0
}
var tmp15 int;
tmp16, err := this.Last()
if err != nil {
return 0, err
}
if (tmp16 >= 5) {
tmp17, err := this.Last()
if err != nil {
return 0, err
}
tmp15 = this.Groups[tmp17 - 5].Value << 35
} else {
tmp15 = 0
}
var tmp18 int;
tmp19, err := this.Last()
if err != nil {
return 0, err
}
if (tmp19 >= 6) {
tmp20, err := this.Last()
if err != nil {
return 0, err
}
tmp18 = this.Groups[tmp20 - 6].Value << 42
} else {
tmp18 = 0
}
var tmp21 int;
tmp22, err := this.Last()
if err != nil {
return 0, err
}
if (tmp22 >= 7) {
tmp23, err := this.Last()
if err != nil {
return 0, err
}
tmp21 = this.Groups[tmp23 - 7].Value << 49
} else {
tmp21 = 0
}
this.value = uint64(uint64(((((((this.Groups[tmp2].Value + tmp3) + tmp6) + tmp9) + tmp12) + tmp15) + tmp18) + tmp21))
return this.value, nil
}
/**
* One byte group, clearly divided into 7-bit "value" chunk and 1-bit "continuation" flag.
*/
type VlqBase128Be_Group struct {
HasNext bool
Value uint64
_io *kaitai.Stream
_root *VlqBase128Be
_parent *VlqBase128Be
}
func NewVlqBase128Be_Group() *VlqBase128Be_Group {
return &VlqBase128Be_Group{
}
}
func (this VlqBase128Be_Group) IO_() *kaitai.Stream {
return this._io
}
func (this *VlqBase128Be_Group) Read(io *kaitai.Stream, parent *VlqBase128Be, root *VlqBase128Be) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp24, err := this._io.ReadBitsIntBe(1)
if err != nil {
return err
}
this.HasNext = tmp24 != 0
tmp25, err := this._io.ReadBitsIntBe(7)
if err != nil {
return err
}
this.Value = tmp25
return err
}
/**
* If true, then we have more bytes to read
*/
/**
* The 7-bit (base128) numeric value chunk of this group
*/