1
1
mirror of https://github.com/wader/fq.git synced 2024-12-25 22:34:14 +03:00
fq/pkg/bitio/sectiontreader.go

83 lines
1.8 KiB
Go
Raw Normal View History

package bitio
import (
"io"
)
2022-02-09 03:22:51 +03:00
// SectionReader is a bitio.BitReaderAtSeeker reading a section of a bitio.ReaderAt.
// Similar to io.SectionReader.
type SectionReader struct {
r ReaderAt
bitBase int64
bitOff int64
bitLimit int64
}
2022-02-09 03:22:51 +03:00
// NewSectionReader returns a new bitio.SectionReader.
func NewSectionReader(r ReaderAt, bitOff int64, nBits int64) *SectionReader {
return &SectionReader{
r: r,
bitBase: bitOff,
bitOff: bitOff,
bitLimit: bitOff + nBits,
}
}
func (r *SectionReader) ReadBitsAt(p []byte, nBits int64, bitOff int64) (int64, error) {
if bitOff < 0 || bitOff >= r.bitLimit-r.bitBase {
return 0, io.EOF
}
bitOff += r.bitBase
if maxBits := r.bitLimit - bitOff; nBits > maxBits {
nBits = maxBits
rBits, err := r.r.ReadBitsAt(p, nBits, bitOff)
return rBits, err
}
return r.r.ReadBitsAt(p, nBits, bitOff)
}
func (r *SectionReader) ReadBits(p []byte, nBits int64) (n int64, err error) {
rBits, err := r.ReadBitsAt(p, nBits, r.bitOff-r.bitBase)
r.bitOff += rBits
return rBits, err
}
func (r *SectionReader) SeekBits(bitOff int64, whence int) (int64, error) {
switch whence {
case io.SeekStart:
bitOff += r.bitBase
case io.SeekCurrent:
bitOff += r.bitOff
case io.SeekEnd:
bitOff += r.bitLimit
default:
panic("unknown whence")
}
if bitOff < r.bitBase {
return 0, ErrOffset
}
r.bitOff = bitOff
return bitOff - r.bitBase, nil
}
func (r *SectionReader) CloneReader() (Reader, error) {
return r.CloneReaderAtSeeker()
}
func (r *SectionReader) CloneReadSeeker() (ReadSeeker, error) {
return r.CloneReaderAtSeeker()
}
func (r *SectionReader) CloneReaderSeeker() (ReadAtSeeker, error) {
return r.CloneReaderAtSeeker()
}
func (r *SectionReader) CloneReaderAtSeeker() (ReaderAtSeeker, error) {
return &SectionReader{
r: r.r,
bitBase: r.bitBase,
bitOff: r.bitBase,
bitLimit: r.bitLimit,
}, nil
}