in pkg/unpack/reader.go [98:158]
func (r *UnpackReader) Read(p []byte) (int, error) {
if len(p) == 0 {
return 0, nil
}
if r.off >= r.totalDigits {
return 0, io.EOF
}
written := 0
read := 0
dpw := ycd.DigitsPerWord(r.radix)
start, packedN, pre, post := ToPackedOffsets(r.off, r.blockSize, int64(len(p)), dpw)
if r.seeked {
if _, err := r.rd.Seek(start, io.SeekStart); err != nil {
return written, err
}
r.unread = nil
r.seeked = false
}
packed := make([]byte, packedN)
if len(r.unread) > 0 {
read += copy(packed, r.unread)
if post == 0 || packedN > 2*WordSize {
r.unread = nil
}
}
n, err := io.ReadFull(r.rd, packed[read:])
read += n
remaining := len(p)
if remaining > int(r.totalDigits-r.off) {
remaining = int(r.totalDigits - r.off)
}
n, perr := r.unpack(p[:remaining], packed[:read], r.off, pre)
r.off += int64(n)
written += n
if read%WordSize != 0 {
return written, fmt.Errorf("off %v, read bytes %v: %w", r.off, n, ErrNotFullWord)
}
if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
return written, fmt.Errorf("read error at off %v: %w", r.off, err)
}
if perr != nil {
poff, _ := r.rd.Seek(0, io.SeekCurrent)
return written, fmt.Errorf("unpack error at off %v, packed off %v: %w", r.off, poff, err)
}
if int64(read) == packedN && post > 0 {
r.unread = make([]byte, WordSize)
copy(r.unread, packed[read-WordSize:])
}
if err == io.ErrUnexpectedEOF {
return written, io.EOF
}
return written, err
}