package varint

import (
	
	
	
	
)

var (
	ErrOverflow   = errors.New("varints larger than uint63 not supported")
	ErrUnderflow  = errors.New("varints malformed, could not reach the end")
	ErrNotMinimal = errors.New("varint not minimally encoded")
)

const (
	// MaxLenUvarint63 is the maximum number of bytes representing an uvarint in
	// this encoding, supporting a maximum value of 2^63 (uint63), aka
	// MaxValueUvarint63.
	MaxLenUvarint63 = 9

	// MaxValueUvarint63 is the maximum encodable uint63 value.
	MaxValueUvarint63 = (1 << 63) - 1
)

// UvarintSize returns the size (in bytes) of `num` encoded as a unsigned varint.
//
// This may return a size greater than MaxUvarintLen63, which would be an
// illegal value, and would be rejected by readers.
func ( uint64) int {
	 := bits.Len64()
	,  := /7, %7
	 := 
	if  > 0 ||  == 0 {
		++
	}
	return 
}

// ToUvarint converts an unsigned integer to a varint-encoded []byte
func ( uint64) []byte {
	 := make([]byte, UvarintSize())
	 := binary.PutUvarint(, uint64())
	return [:]
}

// FromUvarint reads an unsigned varint from the beginning of buf, returns the
// varint, and the number of bytes read.
func ( []byte) (uint64, int, error) {
	// Modified from the go standard library. Copyright the Go Authors and
	// released under the BSD License.
	var  uint64
	var  uint
	for ,  := range  {
		if ( == 8 &&  >= 0x80) ||  >= MaxLenUvarint63 {
			// this is the 9th and last byte we're willing to read, but it
			// signals there's more (1 in MSB).
			// or this is the >= 10th byte, and for some reason we're still here.
			return 0, 0, ErrOverflow
		}
		if  < 0x80 {
			if  == 0 &&  > 0 {
				return 0, 0, ErrNotMinimal
			}
			return  | uint64()<<,  + 1, nil
		}
		 |= uint64(&0x7f) << 
		 += 7
	}
	return 0, 0, ErrUnderflow
}

// ReadUvarint reads a unsigned varint from the given reader.
func ( io.ByteReader) (uint64, error) {
	// Modified from the go standard library. Copyright the Go Authors and
	// released under the BSD License.
	var  uint64
	var  uint
	for  = 0; ;  += 7 {
		,  := .ReadByte()
		if  != nil {
			if  == io.EOF &&  != 0 {
				// "eof" will look like a success.
				// If we've read part of a value, this is not a
				// success.
				 = io.ErrUnexpectedEOF
			}
			return 0, 
		}
		if ( == 56 &&  >= 0x80) ||  >= (7*MaxLenUvarint63) {
			// this is the 9th and last byte we're willing to read, but it
			// signals there's more (1 in MSB).
			// or this is the >= 10th byte, and for some reason we're still here.
			return 0, ErrOverflow
		}
		if  < 0x80 {
			if  == 0 &&  > 0 {
				return 0, ErrNotMinimal
			}
			return  | uint64()<<, nil
		}
		 |= uint64(&0x7f) << 
	}
}

// PutUvarint is an alias for binary.PutUvarint.
//
// This is provided for convenience so users of this library can avoid built-in
// varint functions and easily audit code for uses of those functions.
//
// Make sure that x is smaller or equal to MaxValueUvarint63, otherwise this
// function will produce values that may be rejected by readers.
func ( []byte,  uint64) int {
	return binary.PutUvarint(, )
}