44 lines
852 B
Go
44 lines
852 B
Go
package media
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
)
|
|
|
|
// ModuloReader reads from a reader in block sizes that are exactly modulo
|
|
// modSize, with any remainder buffered until the next read.
|
|
type ModuloReader struct {
|
|
io.ReadCloser
|
|
|
|
buf bytes.Buffer
|
|
modSize int
|
|
}
|
|
|
|
func NewModuloReader(r io.ReadCloser, modSize int) *ModuloReader {
|
|
return &ModuloReader{ReadCloser: r, modSize: modSize}
|
|
}
|
|
|
|
func (r *ModuloReader) Read(p []byte) (int, error) {
|
|
// err is always io.EOF or nil
|
|
nr1, _ := r.buf.Read(p)
|
|
nr2, err := r.ReadCloser.Read(p[nr1:])
|
|
|
|
nr := nr1 + nr2
|
|
rem := nr % r.modSize
|
|
|
|
// if there was an error, return immediately.
|
|
if err == io.EOF {
|
|
return nr, err
|
|
} else if err != nil {
|
|
return nr - rem, err
|
|
}
|
|
|
|
// write any remainder to the buffer
|
|
if rem != 0 {
|
|
// err is always nil
|
|
_, _ = r.buf.Write(p[nr-rem : nr])
|
|
}
|
|
|
|
return nr - rem, err
|
|
}
|