 5978a0b8f5
			
		
	
	5978a0b8f5
	
	
	
		
			
			- Agent roles and coordination features - Chat API integration testing - New configuration and workspace management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			184 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package multiaddr
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"encoding/binary"
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/multiformats/go-varint"
 | |
| )
 | |
| 
 | |
| // Component is a single multiaddr Component.
 | |
| type Component struct {
 | |
| 	bytes    []byte
 | |
| 	protocol Protocol
 | |
| 	offset   int
 | |
| }
 | |
| 
 | |
| func (c *Component) Bytes() []byte {
 | |
| 	return c.bytes
 | |
| }
 | |
| 
 | |
| func (c *Component) MarshalBinary() ([]byte, error) {
 | |
| 	return c.Bytes(), nil
 | |
| }
 | |
| 
 | |
| func (c *Component) UnmarshalBinary(data []byte) error {
 | |
| 	_, comp, err := readComponent(data)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	*c = comp
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (c *Component) MarshalText() ([]byte, error) {
 | |
| 	return []byte(c.String()), nil
 | |
| }
 | |
| 
 | |
| func (c *Component) UnmarshalText(data []byte) error {
 | |
| 	bytes, err := stringToBytes(string(data))
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	_, comp, err := readComponent(bytes)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	*c = comp
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (c *Component) MarshalJSON() ([]byte, error) {
 | |
| 	txt, err := c.MarshalText()
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return json.Marshal(string(txt))
 | |
| }
 | |
| 
 | |
| func (m *Component) UnmarshalJSON(data []byte) error {
 | |
| 	var v string
 | |
| 	if err := json.Unmarshal(data, &v); err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	return m.UnmarshalText([]byte(v))
 | |
| }
 | |
| 
 | |
| func (c *Component) Equal(o Multiaddr) bool {
 | |
| 	return bytes.Equal(c.bytes, o.Bytes())
 | |
| }
 | |
| 
 | |
| func (c *Component) Protocols() []Protocol {
 | |
| 	return []Protocol{c.protocol}
 | |
| }
 | |
| 
 | |
| func (c *Component) Decapsulate(o Multiaddr) Multiaddr {
 | |
| 	if c.Equal(o) {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return c
 | |
| }
 | |
| 
 | |
| func (c *Component) Encapsulate(o Multiaddr) Multiaddr {
 | |
| 	m := &multiaddr{bytes: c.bytes}
 | |
| 	return m.Encapsulate(o)
 | |
| }
 | |
| 
 | |
| func (c *Component) ValueForProtocol(code int) (string, error) {
 | |
| 	if c.protocol.Code != code {
 | |
| 		return "", ErrProtocolNotFound
 | |
| 	}
 | |
| 	return c.Value(), nil
 | |
| }
 | |
| 
 | |
| func (c *Component) Protocol() Protocol {
 | |
| 	return c.protocol
 | |
| }
 | |
| 
 | |
| func (c *Component) RawValue() []byte {
 | |
| 	return c.bytes[c.offset:]
 | |
| }
 | |
| 
 | |
| func (c *Component) Value() string {
 | |
| 	if c.protocol.Transcoder == nil {
 | |
| 		return ""
 | |
| 	}
 | |
| 	value, err := c.protocol.Transcoder.BytesToString(c.bytes[c.offset:])
 | |
| 	if err != nil {
 | |
| 		// This Component must have been checked.
 | |
| 		panic(err)
 | |
| 	}
 | |
| 	return value
 | |
| }
 | |
| 
 | |
| func (c *Component) String() string {
 | |
| 	var b strings.Builder
 | |
| 	c.writeTo(&b)
 | |
| 	return b.String()
 | |
| }
 | |
| 
 | |
| // writeTo is an efficient, private function for string-formatting a multiaddr.
 | |
| // Trust me, we tend to allocate a lot when doing this.
 | |
| func (c *Component) writeTo(b *strings.Builder) {
 | |
| 	b.WriteByte('/')
 | |
| 	b.WriteString(c.protocol.Name)
 | |
| 	value := c.Value()
 | |
| 	if len(value) == 0 {
 | |
| 		return
 | |
| 	}
 | |
| 	if !(c.protocol.Path && value[0] == '/') {
 | |
| 		b.WriteByte('/')
 | |
| 	}
 | |
| 	b.WriteString(value)
 | |
| }
 | |
| 
 | |
| // NewComponent constructs a new multiaddr component
 | |
| func NewComponent(protocol, value string) (*Component, error) {
 | |
| 	p := ProtocolWithName(protocol)
 | |
| 	if p.Code == 0 {
 | |
| 		return nil, fmt.Errorf("unsupported protocol: %s", protocol)
 | |
| 	}
 | |
| 	if p.Transcoder != nil {
 | |
| 		bts, err := p.Transcoder.StringToBytes(value)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		return newComponent(p, bts), nil
 | |
| 	} else if value != "" {
 | |
| 		return nil, fmt.Errorf("protocol %s doesn't take a value", p.Name)
 | |
| 	}
 | |
| 	return newComponent(p, nil), nil
 | |
| 	// TODO: handle path /?
 | |
| }
 | |
| 
 | |
| func newComponent(protocol Protocol, bvalue []byte) *Component {
 | |
| 	size := len(bvalue)
 | |
| 	size += len(protocol.VCode)
 | |
| 	if protocol.Size < 0 {
 | |
| 		size += varint.UvarintSize(uint64(len(bvalue)))
 | |
| 	}
 | |
| 	maddr := make([]byte, size)
 | |
| 	var offset int
 | |
| 	offset += copy(maddr[offset:], protocol.VCode)
 | |
| 	if protocol.Size < 0 {
 | |
| 		offset += binary.PutUvarint(maddr[offset:], uint64(len(bvalue)))
 | |
| 	}
 | |
| 	copy(maddr[offset:], bvalue)
 | |
| 
 | |
| 	// For debugging
 | |
| 	if len(maddr) != offset+len(bvalue) {
 | |
| 		panic("incorrect length")
 | |
| 	}
 | |
| 
 | |
| 	return &Component{
 | |
| 		bytes:    maddr,
 | |
| 		protocol: protocol,
 | |
| 		offset:   offset,
 | |
| 	}
 | |
| }
 |