scream/src/github.com/belak/irc/conn.go

81 lines
1.8 KiB
Go

package irc
import (
"bufio"
"fmt"
"io"
"strings"
)
// Conn represents a simple IRC client.
type Conn struct {
// DebugCallback is a callback for every line of input and
// output. It is meant for debugging and is not guaranteed to
// be stable.
DebugCallback func(line string)
// Internal things
conn io.ReadWriteCloser
in *bufio.Reader
}
// NewConn creates a new Conn
func NewConn(rwc io.ReadWriteCloser) *Conn {
// Create the client
c := &Conn{
func(line string) {},
rwc,
bufio.NewReader(rwc),
}
return c
}
// Write is a simple function which will write the given line to the
// underlying connection.
func (c *Conn) Write(line string) {
c.DebugCallback("--> " + line)
c.conn.Write([]byte(line))
c.conn.Write([]byte("\r\n"))
}
// Writef is a wrapper around the connection's Write method and
// fmt.Sprintf. Simply use it to send a message as you would normally
// use fmt.Printf.
func (c *Conn) Writef(format string, args ...interface{}) {
c.Write(fmt.Sprintf(format, args...))
}
// WriteMessage writes the given message to the stream
func (c *Conn) WriteMessage(m *Message) {
c.Write(m.String())
}
// ReadMessage returns the next message from the stream or an error.
func (c *Conn) ReadMessage() (*Message, error) {
line, err := c.in.ReadString('\n')
if err != nil {
return nil, err
}
c.DebugCallback("<-- " + strings.TrimRight(line, "\r\n"))
// Parse the message from our line
m := ParseMessage(line)
// Now that we have the message parsed, do some preprocessing on it
lastArg := m.Trailing()
// Clean up CTCP stuff so everyone
// doesn't have to parse it manually
if m.Command == "PRIVMSG" && len(lastArg) > 0 && lastArg[0] == '\x01' {
m.Command = "CTCP"
if i := strings.LastIndex(lastArg, "\x01"); i > -1 {
m.Params[len(m.Params)-1] = lastArg[1:i]
}
}
return m, nil
}