85 lines
1.2 KiB
Go
85 lines
1.2 KiB
Go
// vim:ts=4:sts=4:sw=4:noet:tw=72
|
|
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type IRCConn struct {
|
|
conn net.Conn
|
|
read chan string
|
|
write chan string
|
|
done chan bool
|
|
closed bool
|
|
}
|
|
|
|
func NewIRCConn(conn net.Conn, done chan bool) *IRCConn {
|
|
read := make(chan string, 1024)
|
|
write := make(chan string, 1024)
|
|
|
|
c := &IRCConn{conn: conn, read: read, write: write, done: done, closed: false}
|
|
|
|
go c.reader()
|
|
go c.writer()
|
|
|
|
return c
|
|
}
|
|
|
|
func (c *IRCConn) Read() string {
|
|
select {
|
|
case s := <-c.read:
|
|
return s
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func (c *IRCConn) Write(s string) {
|
|
c.write <- s
|
|
}
|
|
|
|
func (c *IRCConn) Close() {
|
|
c.conn.Close()
|
|
c.closed = true
|
|
}
|
|
|
|
func (c *IRCConn) reader() {
|
|
input := bufio.NewReader(c.conn)
|
|
for {
|
|
s, err := input.ReadString('\n')
|
|
if err != nil {
|
|
c.done <- true
|
|
return
|
|
}
|
|
s = strings.Trim(s, "\r\n")
|
|
c.read <- s
|
|
}
|
|
}
|
|
|
|
func (c *IRCConn) writer() {
|
|
for {
|
|
select {
|
|
case line := <-c.write:
|
|
written := 0
|
|
bytes := []byte(line + "\r\n")
|
|
for written < len(line) {
|
|
n, err := c.conn.Write(bytes[written:])
|
|
if err != nil {
|
|
c.done <- true
|
|
return
|
|
}
|
|
written += n
|
|
}
|
|
default:
|
|
if c.closed {
|
|
return
|
|
}
|
|
time.Sleep(1 * time.Millisecond)
|
|
}
|
|
}
|
|
}
|