package extraio

import (
	
)

// PadReader is an io.Reader that always adds non-zero padding on EOF. The
// the value of the padding bytes is equal to the length of the padding.
type PadReader struct {
	reader    io.Reader
	blockSize uint8

	incomplete int   // mutable
	padding    uint8 // mutable
	fillByte   byte  // mutable
}

// NewPadReader returns a new reader that pads r with the given block size.
// If blockSize is zero, PadReader is a no-op, i.e. it does not attempt to
// add padding to the underlying reader.
func ( io.Reader,  uint8) *PadReader {
	return &PadReader{
		reader:    ,
		blockSize: ,
	}
}

// Reset resets the reader’s state.
func ( *PadReader) () {
	.incomplete = 0
	.padding = 0
	.fillByte = 0
}

// Read implements the io.Reader interface. It reads from the underlying
// io.Reader until EOF and then writes padding into the read buffer.
func ( *PadReader) ( []byte) (int, error) {
	if .fillByte != 0 {
		return .pad()
	}

	,  := .reader.Read()
	if .blockSize == 0 {
		return , 
	}
	if  > 0 {
		 := int(.blockSize)
		.incomplete +=  % 
		.incomplete %= 
	}
	if  != io.EOF {
		return , 
	}

	.padding = .blockSize - uint8(.incomplete)
	.fillByte = byte(.padding)

	,  := .pad([:])
	return  + , 
}

// pad writes padding to p.
func ( *PadReader) ( []byte) (int, error) {
	if .padding == 0 {
		return 0, io.EOF
	}

	var  error

	 := len()
	if  := int(.padding);  <=  {
		 = 
		.padding = 0
		 = io.EOF
	} else {
		// Note that !(k <= n) means that n < k <= math.MaxUint8.
		.padding -= uint8()
	}

	for  := 0;  < ; ++ {
		[] = .fillByte
	}

	if .padding == 0 {
		.Reset()
	}

	return , 
}