Skip to content

Instantly share code, notes, and snippets.

@blixt
Last active April 25, 2016 03:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blixt/2160207dbcb166e3e4e414ced3af0562 to your computer and use it in GitHub Desktop.
Save blixt/2160207dbcb166e3e4e414ced3af0562 to your computer and use it in GitHub Desktop.
Non-blocking reader for Go. Probably a bad idea.
package nonblocking
import (
"io"
"time"
)
type NonBlockingReader struct {
ch chan []byte
rd io.Reader
err error
}
func NewNonBlockingReader(r io.Reader) *NonBlockingReader {
nbr := &NonBlockingReader{
ch: make(chan []byte),
rd: r,
}
go nbr.pipe()
return nbr
}
func (nbr *NonBlockingReader) pipe() {
d1 := make([]byte, 1024)
d2 := make([]byte, 1024)
for {
n, err := nbr.rd.Read(d1)
if n > 0 {
nbr.ch <- d1[:n]
d1, d2 = d2, d1
}
if err != nil {
nbr.err = err
close(nbr.ch)
break
}
}
}
func (nbr *NonBlockingReader) Read(p []byte) (n int, err error) {
// TODO: Empty channel completely?
select {
case d := <-nbr.ch:
if len(d) > len(p) {
// TODO: Buffer data
panic("NonBlockingReader: couldn't fit data")
}
n = copy(p, d)
return
case <-time.After(1 * time.Millisecond):
return 0, nbr.err
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment