171 lines
3.4 KiB
Go
171 lines
3.4 KiB
Go
// Copyright 2018 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Package leb128 implements LEB128 integer encoding.
|
|
package leb128
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
// MustReadVarInt32 returns an int32 from r or panics.
|
|
func MustReadVarInt32(r io.Reader) int32 {
|
|
i32, err := ReadVarInt32(r)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return i32
|
|
}
|
|
|
|
// MustReadVarInt64 returns an int64 from r or panics.
|
|
func MustReadVarInt64(r io.Reader) int64 {
|
|
i64, err := ReadVarInt64(r)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return i64
|
|
}
|
|
|
|
// MustReadVarUint32 returns an uint32 from r or panics.
|
|
func MustReadVarUint32(r io.Reader) uint32 {
|
|
u32, err := ReadVarUint32(r)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return u32
|
|
}
|
|
|
|
// MustReadVarUint64 returns an uint64 from r or panics.
|
|
func MustReadVarUint64(r io.Reader) uint64 {
|
|
u64, err := ReadVarUint64(r)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return u64
|
|
}
|
|
|
|
// Copied rom http://dwarfstd.org/doc/Dwarf3.pdf.
|
|
|
|
// ReadVarUint32 tries to read a uint32 from r.
|
|
func ReadVarUint32(r io.Reader) (uint32, error) {
|
|
u64, err := ReadVarUint64(r)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return uint32(u64), nil
|
|
}
|
|
|
|
// ReadVarUint64 tries to read a uint64 from r.
|
|
func ReadVarUint64(r io.Reader) (uint64, error) {
|
|
var result uint64
|
|
var shift uint64
|
|
buf := make([]byte, 1)
|
|
for {
|
|
if _, err := r.Read(buf); err != nil {
|
|
return 0, err
|
|
}
|
|
v := uint64(buf[0])
|
|
result |= (v & 0x7F) << shift
|
|
if v&0x80 == 0 {
|
|
return result, nil
|
|
}
|
|
shift += 7
|
|
}
|
|
|
|
}
|
|
|
|
// ReadVarInt32 tries to read a int32 from r.
|
|
func ReadVarInt32(r io.Reader) (int32, error) {
|
|
i64, err := ReadVarInt64(r)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return int32(i64), nil
|
|
}
|
|
|
|
// ReadVarInt64 tries to read a int64 from r.
|
|
func ReadVarInt64(r io.Reader) (int64, error) {
|
|
var result int64
|
|
var shift uint64
|
|
size := uint64(32)
|
|
buf := make([]byte, 1)
|
|
for {
|
|
if _, err := r.Read(buf); err != nil {
|
|
return 0, err
|
|
}
|
|
v := int64(buf[0])
|
|
result |= (v & 0x7F) << shift
|
|
shift += 7
|
|
if v&0x80 == 0 {
|
|
if (shift < size) && (v&0x40 != 0) {
|
|
result |= (^0 << shift)
|
|
}
|
|
return result, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// WriteVarUint32 writes u to w.
|
|
func WriteVarUint32(w io.Writer, u uint32) error {
|
|
var b []byte
|
|
_, err := w.Write(appendUleb128(b, uint64(u)))
|
|
return err
|
|
}
|
|
|
|
// WriteVarUint64 writes u to w.
|
|
func WriteVarUint64(w io.Writer, u uint64) error {
|
|
var b []byte
|
|
_, err := w.Write(appendUleb128(b, u))
|
|
return err
|
|
}
|
|
|
|
// WriteVarInt32 writes u to w.
|
|
func WriteVarInt32(w io.Writer, i int32) error {
|
|
var b []byte
|
|
_, err := w.Write(appendSleb128(b, int64(i)))
|
|
return err
|
|
}
|
|
|
|
// WriteVarInt64 writes u to w.
|
|
func WriteVarInt64(w io.Writer, i int64) error {
|
|
var b []byte
|
|
_, err := w.Write(appendSleb128(b, i))
|
|
return err
|
|
}
|
|
|
|
// Copied from https://github.com/golang/go/blob/master/src/cmd/internal/dwarf/dwarf.go.
|
|
|
|
// appendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
|
|
func appendUleb128(b []byte, v uint64) []byte {
|
|
for {
|
|
c := uint8(v & 0x7f)
|
|
v >>= 7
|
|
if v != 0 {
|
|
c |= 0x80
|
|
}
|
|
b = append(b, c)
|
|
if c&0x80 == 0 {
|
|
break
|
|
}
|
|
}
|
|
return b
|
|
}
|
|
|
|
// appendSleb128 appends v to b using DWARF's signed LEB128 encoding.
|
|
func appendSleb128(b []byte, v int64) []byte {
|
|
for {
|
|
c := uint8(v & 0x7f)
|
|
s := uint8(v & 0x40)
|
|
v >>= 7
|
|
if (v != -1 || s == 0) && (v != 0 || s != 0) {
|
|
c |= 0x80
|
|
}
|
|
b = append(b, c)
|
|
if c&0x80 == 0 {
|
|
break
|
|
}
|
|
}
|
|
return b
|
|
}
|