package multiaddr

import (
	
	
	

	
)

func stringToBytes( string) ([]byte, error) {
	// consume trailing slashes
	 = strings.TrimRight(, "/")

	var  bytes.Buffer
	 := strings.Split(, "/")

	if [0] != "" {
		return nil, fmt.Errorf("failed to parse multiaddr %q: must begin with /", )
	}

	// consume first empty elem
	 = [1:]

	if len() == 0 {
		return nil, fmt.Errorf("failed to parse multiaddr %q: empty multiaddr", )
	}

	for len() > 0 {
		 := [0]
		 := ProtocolWithName()
		if .Code == 0 {
			return nil, fmt.Errorf("failed to parse multiaddr %q: unknown protocol %s", , [0])
		}
		_, _ = .Write(.VCode)
		 = [1:]

		if .Size == 0 { // no length.
			continue
		}

		if len() < 1 {
			return nil, fmt.Errorf("failed to parse multiaddr %q: unexpected end of multiaddr", )
		}

		if .Path {
			// it's a path protocol (terminal).
			// consume the rest of the address as the next component.
			 = []string{"/" + strings.Join(, "/")}
		}

		,  := .Transcoder.StringToBytes([0])
		if  != nil {
			return nil, fmt.Errorf("failed to parse multiaddr %q: invalid value %q for protocol %s: %s", , [0], .Name, )
		}
		 = .Transcoder.ValidateBytes()
		if  != nil {
			return nil, fmt.Errorf("failed to validate multiaddr %q: invalid value %q for protocol %s: %w", , [0], .Name, )
		}
		if .Size < 0 { // varint size.
			_, _ = .Write(varint.ToUvarint(uint64(len())))
		}
		.Write()
		 = [1:]
	}

	return .Bytes(), nil
}

func readComponent( []byte) (int, *Component, error) {
	var  int
	, ,  := ReadVarintCode()
	if  != nil {
		return 0, nil, 
	}
	 += 

	 := ProtocolWithCode()
	if .Code == 0 {
		return 0, nil, fmt.Errorf("no protocol with code %d", )
	}
	 := protocolPtrByCode[]
	if  == nil {
		return 0, nil, fmt.Errorf("no protocol with code %d", )
	}

	if .Size == 0 {
		 := &Component{
			bytes:         string([:]),
			valueStartIdx: ,
			protocol:      ,
		}

		 := validateComponent()
		if  != nil {
			return 0, nil, 
		}

		return , , nil
	}

	var  int
	if .Size < 0 {
		// varint
		var  int
		, ,  = ReadVarintCode([:])
		if  != nil {
			return 0, nil, 
		}
		 += 
	} else {
		// Size is in bits, but we operate on bytes
		 = .Size / 8
	}

	if len([:]) <  ||  <= 0 {
		return 0, nil, fmt.Errorf("invalid value for size %d", len([:]))
	}

	 := &Component{
		bytes:         string([:+]),
		protocol:      ,
		valueStartIdx: ,
	}
	 = validateComponent()
	if  != nil {
		return 0, nil, 
	}

	return  + , , 
}

func readMultiaddr( []byte) (int, Multiaddr, error) {
	if len() == 0 {
		return 0, nil, fmt.Errorf("empty multiaddr")
	}

	var  Multiaddr
	 := 0
	 := false
	for len() > 0 {
		, ,  := readComponent()
		if  != nil {
			return 0, nil, 
		}
		 = [:]
		 += 

		if  {
			// It is an error to have another component after a path component.
			return , nil, fmt.Errorf("unexpected component after path component")
		}
		 = .protocol.Path
		 = append(, *)
	}
	return , , nil
}