func()

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
}