From 986009402068f88f010590621a82a959f33cdc3b Mon Sep 17 00:00:00 2001 From: Daniel Oaks Date: Wed, 15 Jun 2016 21:21:45 +1000 Subject: [PATCH] socket: Use updated socket code --- irc/client.go | 6 ++- irc/socket.go | 108 +++++++++++++++++++++----------------------------- 2 files changed, 49 insertions(+), 65 deletions(-) diff --git a/irc/client.go b/irc/client.go index 41bbe449..7fc5d63c 100644 --- a/irc/client.go +++ b/irc/client.go @@ -35,6 +35,7 @@ type Client struct { func NewClient(server *Server, conn net.Conn) *Client { now := time.Now() + socket := NewSocket(conn) client := &Client{ atime: now, authorized: server.password == nil, @@ -44,7 +45,7 @@ func NewClient(server *Server, conn net.Conn) *Client { ctime: now, flags: make(map[UserMode]bool), server: server, - socket: NewSocket(conn), + socket: &socket, } client.Touch() go client.run() @@ -265,7 +266,8 @@ func (client *Client) ChangeNickname(nickname Name) { } func (client *Client) Reply(reply string) error { - return client.socket.Write(reply) + //TODO(dan): We'll be passing around real message objects instead of raw strings + return client.socket.WriteLine(reply) } func (client *Client) Quit(message Text) { diff --git a/irc/socket.go b/irc/socket.go index d193fd8a..eac2e8b4 100644 --- a/irc/socket.go +++ b/irc/socket.go @@ -4,92 +4,74 @@ import ( "bufio" "io" "net" + "strings" ) -const ( - R = '→' - W = '←' -) - +// Socket represents an IRC socket. type Socket struct { - closed bool - conn net.Conn - scanner *bufio.Scanner - writer *bufio.Writer + Closed bool + conn net.Conn + reader *bufio.Reader } -func NewSocket(conn net.Conn) *Socket { - return &Socket{ - conn: conn, - scanner: bufio.NewScanner(conn), - writer: bufio.NewWriter(conn), +// NewSocket returns a new Socket. +func NewSocket(conn net.Conn) Socket { + return Socket{ + conn: conn, + reader: bufio.NewReader(conn), } } -func (socket *Socket) String() string { - return socket.conn.RemoteAddr().String() -} - +// Close stops a Socket from being able to send/receive any more data. func (socket *Socket) Close() { - if socket.closed { + if socket.Closed { return } - socket.closed = true + socket.Closed = true socket.conn.Close() - Log.debug.Printf("%s closed", socket) } -func (socket *Socket) Read() (line string, err error) { - if socket.closed { - err = io.EOF - return +// Read returns a single IRC line from a Socket. +func (socket *Socket) Read() (string, error) { + if socket.Closed { + return "", io.EOF } - for socket.scanner.Scan() { - line = socket.scanner.Text() - if len(line) == 0 { - continue - } - Log.debug.Printf("%s → %s", socket, line) - return + lineBytes, err := socket.reader.ReadBytes('\n') + + // convert bytes to string + line := string(lineBytes[:]) + + // read last message properly (such as ERROR/QUIT/etc), just fail next reads/writes + if err == io.EOF { + socket.Close() } - err = socket.scanner.Err() - socket.isError(err, R) - if err == nil { - err = io.EOF + if err == io.EOF && strings.TrimSpace(line) != "" { + // don't do anything + } else if err != nil { + return "", err } - return + + return strings.TrimRight(line, "\r\n"), nil } -func (socket *Socket) Write(line string) (err error) { - if socket.closed { - err = io.EOF - return +// Write sends the given string out of Socket. +func (socket *Socket) Write(data string) error { + if socket.Closed { + return io.EOF } - if _, err = socket.writer.WriteString(line); socket.isError(err, W) { - return - } - - if _, err = socket.writer.WriteString(CRLF); socket.isError(err, W) { - return - } - - if err = socket.writer.Flush(); socket.isError(err, W) { - return - } - - Log.debug.Printf("%s ← %s", socket, line) - return -} - -func (socket *Socket) isError(err error, dir rune) bool { + // write data + _, err := socket.conn.Write([]byte(data)) if err != nil { - if err != io.EOF { - Log.debug.Printf("%s %c error: %s", socket, dir, err) - } - return true + socket.Close() + return err } - return false + return nil +} + +// WriteLine writes the given line out of Socket. +func (socket *Socket) WriteLine(line string) error { + return socket.Write(line + "\r\n") }