// 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 (
	
	
	
	
)

// 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 ( []byte,  bool) *Reader {
	 := Reader{
		b:        ,
		readonly: ,
	}
	return &
}

func ( *Reader) ( []byte) (int, error) {
	 := len()
	 := .b[.off:]
	if len() <  {
		 = len()
	}
	copy(, )
	.off += int64()
	return , nil
}

func ( *Reader) ( int64,  int) ( int64,  error) {
	switch  {
	case io.SeekStart:
		if  < 0 ||  > int64(len(.b)) {
			return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", , len(.b))
		}
		.off = 
		return , nil
	case io.SeekCurrent:
		 := .off + 
		if  < 0 ||  > int64(len(.b)) {
			return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", , len(.b))
		}
		.off = 
		return .off, nil
	case io.SeekEnd:
		 := int64(len(.b)) + 
		if  < 0 ||  > int64(len(.b)) {
			return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", , len(.b))
		}
		.off = 
		return .off, nil
	}
	// other modes are not supported
	return 0, fmt.Errorf("unsupported seek mode %d", )
}

func ( *Reader) () int64 {
	return .off
}

func ( *Reader) () uint8 {
	 := uint8(.b[int(.off)])
	.off += 1
	return 
}

func ( *Reader) () uint32 {
	 := int(.off) + 4
	 := binary.LittleEndian.Uint32(.b[int(.off)::])
	.off += 4
	return 
}

func ( *Reader) () uint64 {
	 := int(.off) + 8
	 := binary.LittleEndian.Uint64(.b[int(.off)::])
	.off += 8
	return 
}

func ( *Reader) () ( uint64) {
	var  uint

	for {
		 := .b[.off]
		.off++
		 |= (uint64(&0x7F) << )
		if &0x80 == 0 {
			break
		}
		 += 7
	}
	return
}

func ( *Reader) ( int64) string {
	 := .b[.off : .off+]
	.off += 
	if .readonly {
		return toString() // backed by RO memory, ok to make unsafe string
	}
	return string()
}

func toString( []byte) string {
	if len() == 0 {
		return ""
	}
	return unsafe.String(&[0], len())
}