remote-mic/networking/reader.go

58 lines
1.3 KiB
Go

package networking
import (
"io"
)
type AsyncReader struct {
BufSize int
stream io.ReadCloser
dataChan chan []byte
stopFlag bool
}
// NewListen starts listening for a single connection on the given address.
// This method blocks until this is done.
func NewAsyncReader(reader io.ReadCloser) *AsyncReader {
return &AsyncReader{
BufSize: defaultBufSize,
stream: reader,
stopFlag: false,
}
}
// RecvChan returns a read-only channel of byte slices and starts
// receiving and pushing data into it asynchronously.
// The channel is closed when the sender closes the connection.
// Use this to read bytes from the network connection.
// The data read is owned by the reader, it is thread-safe to modify.
func (ar *AsyncReader) RecvChan() <-chan []byte {
ar.dataChan = make(chan []byte)
go ar.recvLoop()
return ar.dataChan
}
func (ar *AsyncReader) recvLoop() {
buf := make([]byte, ar.BufSize)
for !ar.stopFlag {
n, err := ar.stream.Read(buf)
if err != nil {
ar.stopFlag = true
}
if n > 0 {
// the underlying memory of the buffer
// must be copied for thread safety
sendBuf := make([]byte, n)
copy(sendBuf, buf)
ar.dataChan <- sendBuf
}
}
close(ar.dataChan)
}
func (ar *AsyncReader) Close() {
ar.stopFlag = true
ar.stream.Close()
}