| // Copyright 2021 The Go 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 slicereader |
| |
| import ( |
| "encoding/binary" |
| "unsafe" |
| ) |
| |
| // This file contains the helper "SliceReader", a utility for |
| // reading values from a byte slice that may or may not be backed |
| // by a read-only mmap'd region. |
| |
| type Reader struct { |
| b []byte |
| readonly bool |
| off int64 |
| } |
| |
| func NewReader(b []byte, readonly bool) *Reader { |
| r := Reader{ |
| b: b, |
| readonly: readonly, |
| } |
| return &r |
| } |
| |
| func (r *Reader) Read(b []byte) (int, error) { |
| amt := len(b) |
| toread := r.b[r.off:] |
| if len(toread) < amt { |
| amt = len(toread) |
| } |
| copy(b, toread) |
| r.off += int64(amt) |
| return amt, nil |
| } |
| |
| func (r *Reader) SeekTo(off int64) { |
| r.off = off |
| } |
| |
| func (r *Reader) Offset() int64 { |
| return r.off |
| } |
| |
| func (r *Reader) ReadUint8() uint8 { |
| rv := uint8(r.b[int(r.off)]) |
| r.off += 1 |
| return rv |
| } |
| |
| func (r *Reader) ReadUint32() uint32 { |
| end := int(r.off) + 4 |
| rv := binary.LittleEndian.Uint32(r.b[int(r.off):end:end]) |
| r.off += 4 |
| return rv |
| } |
| |
| func (r *Reader) ReadUint64() uint64 { |
| end := int(r.off) + 8 |
| rv := binary.LittleEndian.Uint64(r.b[int(r.off):end:end]) |
| r.off += 8 |
| return rv |
| } |
| |
| func (r *Reader) ReadULEB128() (value uint64) { |
| var shift uint |
| |
| for { |
| b := r.b[r.off] |
| r.off++ |
| value |= (uint64(b&0x7F) << shift) |
| if b&0x80 == 0 { |
| break |
| } |
| shift += 7 |
| } |
| return |
| } |
| |
| func (r *Reader) ReadString(len int64) string { |
| b := r.b[r.off : r.off+len] |
| r.off += len |
| if r.readonly { |
| return toString(b) // backed by RO memory, ok to make unsafe string |
| } |
| return string(b) |
| } |
| |
| func toString(b []byte) string { |
| if len(b) == 0 { |
| return "" |
| } |
| return unsafe.String(&b[0], len(b)) |
| } |