package http3

import (
	

	
)

// CapsuleType is the type of the capsule
type CapsuleType uint64

// CapsuleProtocolHeader is the header value used to advertise support for the capsule protocol
const CapsuleProtocolHeader = "Capsule-Protocol"

type exactReader struct {
	R io.LimitedReader
}

func ( *exactReader) ( []byte) (int, error) {
	,  := .R.Read()
	if  == io.EOF && .R.N > 0 {
		return , io.ErrUnexpectedEOF
	}
	return , 
}

type countingByteReader struct {
	io.ByteReader
	Read int
}

func ( *countingByteReader) () (byte, error) {
	,  := .ByteReader.ReadByte()
	if  == nil {
		.Read++
	}
	return , 
}

// ParseCapsule parses the header of a Capsule.
// It returns an io.Reader that can be used to read the Capsule value.
// The Capsule value must be read entirely (i.e. until the io.EOF) before using r again.
func ( quicvarint.Reader) (CapsuleType, io.Reader, error) {
	 := countingByteReader{ByteReader: }
	,  := quicvarint.Read(&)
	if  != nil {
		// If an io.EOF is returned without consuming any bytes, return it unmodified.
		// Otherwise, return an io.ErrUnexpectedEOF.
		if  == io.EOF && .Read > 0 {
			return 0, nil, io.ErrUnexpectedEOF
		}
		return 0, nil, 
	}
	,  := quicvarint.Read()
	if  != nil {
		if  == io.EOF {
			return 0, nil, io.ErrUnexpectedEOF
		}
		return 0, nil, 
	}
	return CapsuleType(), &exactReader{R: io.LimitedReader{R: , N: int64()}}, nil
}

// WriteCapsule writes a capsule
func ( quicvarint.Writer,  CapsuleType,  []byte) error {
	 := make([]byte, 0, 16)
	 = quicvarint.Append(, uint64())
	 = quicvarint.Append(, uint64(len()))
	if ,  := .Write();  != nil {
		return 
	}
	,  := .Write()
	return 
}