package extraio

import (
	
	
)

// ErrExceededReadLimit is an error that HardLimitedReader returns when it
// exceeds read limit.
var ErrExceededReadLimit = errors.New("extraio: exceeded read limit")

// HardLimitedReader reads at most n bytes from the underlying reader and
// returns ErrExceededReadLimit if io.EOF is not reached once the limit is
// exceeded.
type HardLimitedReader struct {
	reader    io.Reader
	limit     uint64
	readCount uint64 // mutable
}

// HardLimitReader returns a Reader that reads from r but stops with an error
// after n bytes.
func ( io.Reader,  uint64) *HardLimitedReader {
	return &HardLimitedReader{
		reader: ,
		limit:  ,
	}
}

// Reset resets the reader’s state.
func ( *HardLimitedReader) () {
	.readCount = 0
}

// Read implements the io.Reader interface. If the limit has been reached, it
// returns ErrExceededReadLimit error. Otherwise it reads from the underlying
// io.Reader.
func ( *HardLimitedReader) ( []byte) (int, error) {
	if .readCount == .limit {
		return 0, ErrExceededReadLimit
	}

	// Do not read more than the remaining limit. This also guarantees that
	// n will not overflow or exceed limit on addition to readCount.
	 := .limit - .readCount
	if uint64(len()) >  {
		 = [:]
	}

	,  := .reader.Read()
	if  > 0 {
		.readCount += uint64()
	}
	if  == io.EOF {
		return , 
	}
	return , 
}