func (m *Message) Len() (length int) {
	if m.Prefix != nil {
		length = m.Prefix.Len() + 2  
	}
	length = length + len(m.Command)
	if len(m.Params) > 0 {
		length = length + len(m.Params)
		for _, param := range m.Params {
			length = length + len(param)
		}
	}
	if len(m.Trailing) > 0 || m.EmptyTrailing {
		length = length + len(m.Trailing) + 2  
	}
	return
}
Len calculates the length of the string representation of this message.
package irc
import (
	"bytes"
	"strings"
)
const (
	prefix     byte = 0x3A  
	prefixUser byte = 0x21  
	prefixHost byte = 0x40  
	space      byte = 0x20  
	maxLength = 510  
)
func cutsetFunc(r rune) bool {
	return r == '\r' || r == '\n'
}
type Sender interface {
	Send(*Message) error
}
type Prefix struct {
	Name string  
	User string  
	Host string  
}
func ParsePrefix(raw string) (p *Prefix) {
	p = new(Prefix)
	user := indexByte(raw, prefixUser)
	host := indexByte(raw, prefixHost)
	switch {
	case user > 0 && host > user:
		p.Name = raw[:user]
		p.User = raw[user+1 : host]
		p.Host = raw[host+1:]
	case user > 0:
		p.Name = raw[:user]
		p.User = raw[user+1:]
	case host > 0:
		p.Name = raw[:host]
		p.Host = raw[host+1:]
	default:
		p.Name = raw
	}
	return p
}
func (p *Prefix) Len() (length int) {
	length = len(p.Name)
	if len(p.User) > 0 {
		length = length + len(p.User) + 1
	}
	if len(p.Host) > 0 {
		length = length + len(p.Host) + 1
	}
	return
}
func (p *Prefix) Bytes() []byte {
	buffer := new(bytes.Buffer)
	p.writeTo(buffer)
	return buffer.Bytes()
}
func (p *Prefix) String() (s string) {
	s = p.Name
	if len(p.User) > 0 {
		s = s + string(prefixUser) + p.User
	}
	if len(p.Host) > 0 {
		s = s + string(prefixHost) + p.Host
	}
	return
}
func (p *Prefix) IsHostmask() bool {
	return len(p.User) > 0 && len(p.Host) > 0
}
func (p *Prefix) IsServer() bool {
	return len(p.User) <= 0 && len(p.Host) <= 0  
}
func (p *Prefix) writeTo(buffer *bytes.Buffer) {
	buffer.WriteString(p.Name)
	if len(p.User) > 0 {
		buffer.WriteByte(prefixUser)
		buffer.WriteString(p.User)
	}
	if len(p.Host) > 0 {
		buffer.WriteByte(prefixHost)
		buffer.WriteString(p.Host)
	}
	return
}
type Message struct {
	*Prefix
	Command  string
	Params   []string
	Trailing string
	EmptyTrailing bool
}
func ParseMessage(raw string) (m *Message) {
	if raw = strings.TrimFunc(raw, cutsetFunc); len(raw) < 2 {
		return nil
	}
	i, j := 0, 0
	m = new(Message)
	if raw[0] == prefix {
		i = indexByte(raw, space)
		if i < 2 {
			return nil
		}
		m.Prefix = ParsePrefix(raw[1:i])
		i++
	}
	j = i + indexByte(raw[i:], space)
	if j > i {
		m.Command = strings.ToUpper(raw[i:j])
	} else {
		m.Command = strings.ToUpper(raw[i:])
		return m
	}
	j++
	i = indexByte(raw[j:], prefix)
	if i < 0 || raw[j+i-1] != space {
		m.Params = strings.Split(raw[j:], string(space))
		return m
	}
	i = i + j
	if i > j {
		m.Params = strings.Split(raw[j:i-1], string(space))
	}
	m.Trailing = raw[i+1:]
	if len(m.Trailing) <= 0 {
		m.EmptyTrailing = true
	}
	return m
}