land/vendor/github.com/go-interpreter/wagon/wasm/leb128/read.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
}