93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
// Copyright 2017 The go-interpreter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Package leb128 provides functions for reading integer values encoded in the
|
|
// Little Endian Base 128 (LEB128) format: https://en.wikipedia.org/wiki/LEB128
|
|
package leb128
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
// ReadVarUint32Size reads a LEB128 encoded unsigned 32-bit integer from r.
|
|
// It returns the integer value, the size of the encoded value (in bytes), and
|
|
// the error (if any).
|
|
func ReadVarUint32Size(r io.Reader) (res uint32, size uint, err error) {
|
|
b := make([]byte, 1)
|
|
var shift uint
|
|
for {
|
|
if _, err = io.ReadFull(r, b); err != nil {
|
|
return
|
|
}
|
|
|
|
size++
|
|
|
|
cur := uint32(b[0])
|
|
res |= (cur & 0x7f) << (shift)
|
|
if cur&0x80 == 0 {
|
|
return res, size, nil
|
|
}
|
|
shift += 7
|
|
}
|
|
}
|
|
|
|
// ReadVarUint32 reads a LEB128 encoded unsigned 32-bit integer from r, and
|
|
// returns the integer value, and the error (if any).
|
|
func ReadVarUint32(r io.Reader) (uint32, error) {
|
|
n, _, err := ReadVarUint32Size(r)
|
|
return n, err
|
|
}
|
|
|
|
// ReadVarint32Size reads a LEB128 encoded signed 32-bit integer from r, and
|
|
// returns the integer value, the size of the encoded value, and the error
|
|
// (if any)
|
|
func ReadVarint32Size(r io.Reader) (res int32, size uint, err error) {
|
|
res64, size, err := ReadVarint64Size(r)
|
|
res = int32(res64)
|
|
return
|
|
}
|
|
|
|
// ReadVarint32 reads a LEB128 encoded signed 32-bit integer from r, and
|
|
// returns the integer value, and the error (if any).
|
|
func ReadVarint32(r io.Reader) (int32, error) {
|
|
n, _, err := ReadVarint32Size(r)
|
|
return n, err
|
|
}
|
|
|
|
// ReadVarint64Size reads a LEB128 encoded signed 64-bit integer from r, and
|
|
// returns the integer value, the size of the encoded value, and the error
|
|
// (if any)
|
|
func ReadVarint64Size(r io.Reader) (res int64, size uint, err error) {
|
|
var shift uint
|
|
var sign int64 = -1
|
|
b := make([]byte, 1)
|
|
|
|
for {
|
|
if _, err = io.ReadFull(r, b); err != nil {
|
|
return
|
|
}
|
|
size++
|
|
|
|
cur := int64(b[0])
|
|
res |= (cur & 0x7f) << shift
|
|
shift += 7
|
|
sign <<= 7
|
|
if cur&0x80 == 0 {
|
|
break
|
|
}
|
|
}
|
|
|
|
if ((sign >> 1) & res) != 0 {
|
|
res |= sign
|
|
}
|
|
return res, size, nil
|
|
}
|
|
|
|
// ReadVarint64 reads a LEB128 encoded signed 64-bit integer from r, and
|
|
// returns the integer value, and the error (if any).
|
|
func ReadVarint64(r io.Reader) (int64, error) {
|
|
n, _, err := ReadVarint64Size(r)
|
|
return n, err
|
|
}
|