socket: Use updated socket code

This commit is contained in:
Daniel Oaks 2016-06-15 21:21:45 +10:00
parent 5027391bff
commit 9860094020
2 changed files with 49 additions and 65 deletions

View File

@ -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) {

View File

@ -4,92 +4,74 @@ import (
"bufio"
"io"
"net"
"strings"
)
const (
R = '→'
W = '←'
)
// Socket represents an IRC socket.
type Socket struct {
closed bool
Closed bool
conn net.Conn
scanner *bufio.Scanner
writer *bufio.Writer
reader *bufio.Reader
}
func NewSocket(conn net.Conn) *Socket {
return &Socket{
// NewSocket returns a new Socket.
func NewSocket(conn net.Conn) Socket {
return Socket{
conn: conn,
scanner: bufio.NewScanner(conn),
writer: bufio.NewWriter(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
}
return
if err == io.EOF && strings.TrimSpace(line) != "" {
// don't do anything
} else if err != nil {
return "", err
}
func (socket *Socket) Write(line string) (err error) {
if socket.closed {
err = io.EOF
return
return strings.TrimRight(line, "\r\n"), nil
}
if _, err = socket.writer.WriteString(line); socket.isError(err, W) {
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(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)
socket.Close()
return err
}
return true
return nil
}
return false
// WriteLine writes the given line out of Socket.
func (socket *Socket) WriteLine(line string) error {
return socket.Write(line + "\r\n")
}