diff --git a/client/Makefile b/client/Makefile index 35dfe19..48c3976 100644 --- a/client/Makefile +++ b/client/Makefile @@ -9,6 +9,7 @@ GOFILES=\ connection.go\ commands.go\ handlers.go\ + line.go\ nickchan.go include $(GOROOT)/src/Make.pkg diff --git a/client/connection.go b/client/connection.go index 81af227..32ff9d3 100644 --- a/client/connection.go +++ b/client/connection.go @@ -64,18 +64,6 @@ type Conn struct { TSFormat string } -// We parse an incoming line into this struct. Line.Cmd is used as the trigger -// name for incoming event handlers, see *Conn.recv() for details. -// Raw =~ ":nick!user@host cmd args[] :text" -// Src == "nick!user@host" -// Cmd == e.g. PRIVMSG, 332 -type Line struct { - Nick, Ident, Host, Src string - Cmd, Raw string - Args []string - Time *time.Time -} - // Creates a new IRC connection object, but doesn't connect to anything so // that you can add event handlers to it. See AddHandler() for details. func New(nick, user, name string) *Conn { @@ -191,51 +179,19 @@ func (conn *Conn) send() { func (conn *Conn) recv() { for { s, err := conn.io.ReadString('\n') - t := conn.Timestamp() if err != nil { conn.error("irc.recv(): %s", err.String()) conn.shutdown() break } s = strings.Trim(s, "\r\n") + t := conn.Timestamp() if conn.Debug { fmt.Println(t.Format(conn.TSFormat) + " <- " + s) } - line := &Line{Raw: s, Time: t} - if s[0] == ':' { - // remove a source and parse it - if idx := strings.Index(s, " "); idx != -1 { - line.Src, s = s[1:idx], s[idx+1:len(s)] - } else { - // pretty sure we shouldn't get here ... - line.Src = s[1:len(s)] - conn.in <- line - continue - } - - // src can be the hostname of the irc server or a nick!user@host - line.Host = line.Src - nidx, uidx := strings.Index(line.Src, "!"), strings.Index(line.Src, "@") - if uidx != -1 && nidx != -1 { - line.Nick = line.Src[0:nidx] - line.Ident = line.Src[nidx+1 : uidx] - line.Host = line.Src[uidx+1 : len(line.Src)] - } - } - - // now we're here, we've parsed a :nick!user@host or :server off - // s should contain "cmd args[] :text" - args := strings.Split(s, " :", 2) - if len(args) > 1 { - args = append(strings.Fields(args[0]), args[1]) - } else { - args = strings.Fields(args[0]) - } - line.Cmd = strings.ToUpper(args[0]) - if len(args) > 1 { - line.Args = args[1:len(args)] - } + line := parseLine(s) + line.Time = t conn.in <- line } } diff --git a/client/line.go b/client/line.go new file mode 100644 index 0000000..d644add --- /dev/null +++ b/client/line.go @@ -0,0 +1,56 @@ +package client + +import ( + "strings" + "time" +) + +// We parse an incoming line into this struct. Line.Cmd is used as the trigger +// name for incoming event handlers, see *Conn.recv() for details. +// Raw =~ ":nick!user@host cmd args[] :text" +// Src == "nick!user@host" +// Cmd == e.g. PRIVMSG, 332 +type Line struct { + Nick, Ident, Host, Src string + Cmd, Raw string + Args []string + Time *time.Time +} + +func parseLine(s string) *Line { + line := &Line{Raw: s} + if s[0] == ':' { + // remove a source and parse it + if idx := strings.Index(s, " "); idx != -1 { + line.Src, s = s[1:idx], s[idx+1:len(s)] + } else { + // pretty sure we shouldn't get here ... + line.Src = s[1:len(s)] + return line + } + + // src can be the hostname of the irc server or a nick!user@host + line.Host = line.Src + nidx, uidx := strings.Index(line.Src, "!"), strings.Index(line.Src, "@") + if uidx != -1 && nidx != -1 { + line.Nick = line.Src[0:nidx] + line.Ident = line.Src[nidx+1 : uidx] + line.Host = line.Src[uidx+1 : len(line.Src)] + } + } + + // now we're here, we've parsed a :nick!user@host or :server off + // s should contain "cmd args[] :text" + args := strings.Split(s, " :", 2) + if len(args) > 1 { + args = append(strings.Fields(args[0]), args[1]) + } else { + args = strings.Fields(args[0]) + } + line.Cmd = strings.ToUpper(args[0]) + if len(args) > 1 { + line.Args = args[1:len(args)] + } + return line +} +