// 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) } } }