package multihash

import (
	
	
	

	
)

// Reader is an io.Reader wrapper that exposes a function
// to read a whole multihash, parse it, and return it.
type Reader interface {
	io.Reader

	ReadMultihash() (Multihash, error)
}

// Writer is an io.Writer wrapper that exposes a function
// to write a whole multihash.
type Writer interface {
	io.Writer

	WriteMultihash(Multihash) error
}

// NewReader wraps an io.Reader with a multihash.Reader
func ( io.Reader) Reader {
	return &mhReader{}
}

// NewWriter wraps an io.Writer with a multihash.Writer
func ( io.Writer) Writer {
	return &mhWriter{}
}

type mhReader struct {
	r io.Reader
}

func ( *mhReader) ( []byte) ( int,  error) {
	return .r.Read()
}

func ( *mhReader) () (byte, error) {
	if ,  := .r.(io.ByteReader);  {
		return .ReadByte()
	}
	var  [1]byte
	,  := .r.Read([:])
	if  == 1 {
		return [0], nil
	}
	if  == nil {
		if  != 0 {
			panic("reader returned an invalid length")
		}
		 = io.ErrNoProgress
	}
	return 0, 
}

func ( *mhReader) () (Multihash, error) {
	,  := varint.ReadUvarint()
	if  != nil {
		return nil, 
	}

	,  := varint.ReadUvarint()
	if  != nil {
		return nil, 
	}
	if  > math.MaxInt32 {
		return nil, errors.New("digest too long, supporting only <= 2^31-1")
	}

	 := make([]byte, varint.UvarintSize()+varint.UvarintSize()+int())
	 := varint.PutUvarint(, )
	 += varint.PutUvarint([:], )
	if ,  := io.ReadFull(.r, [:]);  != nil {
		return nil, 
	}

	return Cast()
}

type mhWriter struct {
	w io.Writer
}

func ( *mhWriter) ( []byte) ( int,  error) {
	return .w.Write()
}

func ( *mhWriter) ( Multihash) error {
	,  := .w.Write([]byte())
	return 
}