func (br *metadataReader) Read(p []byte) (int, error) {
	if br.readOffset+len(p) <= len(br.data) {
		for i := 0; i < len(p); i++ {
			p[i] = br.data[br.readOffset+i]
		}
		br.readOffset += len(p)
		return len(p), nil
	}
	read := 0
	for read < len(p) {
		err := br.parseMetadata()
		if err != nil {
			br.readOffset += read
			return read, err
		}
		err = br.readNextDataBlock()
		if err != nil {
			br.readOffset += read
			return read, err
		}
		for ; read < len(p); read++ {
			if br.readOffset+read < len(br.data) {
				p[read] = br.data[br.readOffset+read]
			} else {
				break
			}
		}
	}
	br.readOffset += read
	if read != len(p) {
		return read, errors.New("didn't read enough data")
	}
	return read, nil
}
Read reads bytes into the given byte slice. Returns the amount of data read.
package squashfs
import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
)
type metadata struct {
	raw        uint16
	size       uint16
	compressed bool
}
type metadataReader struct {
	s          *Reader
	headers    []*metadata
	data       []byte
	offset     int64
	readOffset int
}
func (s *Reader) newMetadataReader(offset int64) (*metadataReader, error) {
	var br metadataReader
	br.s = s
	br.offset = offset
	err := br.parseMetadata()
	if err != nil {
		return nil, err
	}
	err = br.readNextDataBlock()
	if err != nil {
		return nil, err
	}
	return &br, nil
}
func (s *Reader) newMetadataReaderFromInodeRef(ref uint64) (*metadataReader, error) {
	offset, metaOffset := processInodeRef(ref)
	br, err := s.newMetadataReader(int64(s.super.InodeTableStart + offset))
	if err != nil {
		return nil, err
	}
	_, err = br.Seek(int64(metaOffset), io.SeekStart)
	if err != nil {
		return nil, err
	}
	return br, nil
}
func processInodeRef(inodeRef uint64) (tableOffset uint64, metaOffset uint64) {
	tableOffset = inodeRef >> 16
	metaOffset = inodeRef &^ 0xFFFFFFFF0000
	return
}
func (br *metadataReader) parseMetadata() error {
	var raw uint16
	err := binary.Read(io.NewSectionReader(br.s.r, br.offset, 2), binary.LittleEndian, &raw)
	if err != nil {
		return err
	}
	br.offset += 2
	compressed := raw&0x8000 != 0x8000
	size := raw &^ 0x8000
	br.headers = append(br.headers, &metadata{
		raw:        raw,
		size:       size,
		compressed: compressed,
	})
	return nil
}
func (br *metadataReader) readNextDataBlock() error {
	meta := br.headers[len(br.headers)-1]
	r := io.NewSectionReader(br.s.r, br.offset, int64(meta.size))
	if meta.compressed {
		byts, err := br.s.decompressor.Decompress(r)
		if err != nil {
			return err
		}
		br.offset += int64(meta.size)
		br.data = append(br.data, byts...)
		return nil
	}
	var buf bytes.Buffer
	_, err := io.Copy(&buf, r)
	if err != nil {
		return err
	}
	br.offset += int64(meta.size)
	br.data = append(br.data, buf.Bytes()...)
	return nil
}