exercism/go/paasio/paasio.go

110 lines
1.8 KiB
Go

package paasio
import (
"io"
"sync"
)
const testVersion = 3
func NewReadCounter(r io.Reader) ReadCounter {
return &readCounter{
r: r,
lock: new(sync.Mutex),
}
}
type readCounter struct {
r io.Reader
bytesRead int64
ops int
lock *sync.Mutex
}
func (rc *readCounter) Read(p []byte) (int, error) {
m, err := rc.r.Read(p)
rc.lock.Lock()
rc.bytesRead += int64(m)
rc.ops++
rc.lock.Unlock()
return m, err
}
func (rc *readCounter) ReadCount() (n int64, ops int) {
rc.lock.Lock()
n, ops = rc.bytesRead, rc.ops
rc.lock.Unlock()
return n, ops
}
func NewWriteCounter(w io.Writer) WriteCounter {
return &writeCounter{
w: w,
lock: new(sync.Mutex),
}
}
type writeCounter struct {
w io.Writer
bytesWrote int64
ops int
lock *sync.Mutex
}
func (wc *writeCounter) Write(p []byte) (int, error) {
m, err := wc.w.Write(p)
wc.lock.Lock()
wc.bytesWrote += int64(m)
wc.ops++
wc.lock.Unlock()
return m, err
}
func (wc *writeCounter) WriteCount() (n int64, ops int) {
wc.lock.Lock()
n, ops = wc.bytesWrote, wc.ops
wc.lock.Unlock()
return n, ops
}
type ReadWriter interface {
io.Reader
io.Writer
}
func NewReadWriteCounter(rw ReadWriter) ReadWriteCounter {
return &readWriteCounter{
r: NewReadCounter(rw),
w: NewWriteCounter(rw),
}
}
type readWriteCounter struct {
r ReadCounter
w WriteCounter
}
func (rw *readWriteCounter) Read(p []byte) (int, error) {
return rw.r.Read(p)
}
func (rw *readWriteCounter) Write(p []byte) (int, error) {
return rw.w.Write(p)
}
func (rw *readWriteCounter) ReadCount() (n int64, ops int) {
return rw.r.ReadCount()
}
func (rw *readWriteCounter) WriteCount() (n int64, ops int) {
return rw.w.WriteCount()
}
func (nr *nopReader) ReadCount() (n int64, ops int) {
return 0, 0
}
func (nw *nopWriter) WriteCount() (n int64, ops int) {
return 0, 0
}