Example #1
0
// Read reads actual data from the xz stream.
func (r *streamReader) Read(p []byte) (n int, err error) {
	for n < len(p) {
		if r.br == nil {
			bh, hlen, err := readBlockHeader(r.xz)
			if err != nil {
				if err == errIndexIndicator {
					if err = r.readTail(); err != nil {
						return n, err
					}
					return n, io.EOF
				}
				return n, err
			}
			xlog.Debugf("block %v", *bh)
			r.br, err = r.ReaderConfig.newBlockReader(r.xz, bh,
				hlen, r.newHash())
			if err != nil {
				return n, err
			}
		}
		k, err := r.br.Read(p[n:])
		n += k
		if err != nil {
			if err == io.EOF {
				r.index = append(r.index, r.br.record())
				r.br = nil
			} else {
				return n, err
			}
		}
	}
	return n, nil
}
Example #2
0
// newStreamReader creates a new xz stream reader using the given configuration
// parameters. NewReader reads and checks the header of the xz stream.
func (c ReaderConfig) newStreamReader(xz io.Reader) (r *streamReader, err error) {
	if err = c.Verify(); err != nil {
		return nil, err
	}
	data := make([]byte, HeaderLen)
	if _, err := io.ReadFull(xz, data[:4]); err != nil {
		return nil, err
	}
	if bytes.Equal(data[:4], []byte{0, 0, 0, 0}) {
		return nil, errPadding
	}
	if _, err = io.ReadFull(xz, data[4:]); err != nil {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		return nil, err
	}
	r = &streamReader{
		ReaderConfig: c,
		xz:           xz,
		index:        make([]record, 0, 4),
	}
	if err = r.h.UnmarshalBinary(data); err != nil {
		return nil, err
	}
	xlog.Debugf("xz header %s", r.h)
	if r.newHash, err = newHashFunc(r.h.flags); err != nil {
		return nil, err
	}
	return r, nil
}
Example #3
0
// readTail reads the index body and the xz footer.
func (r *streamReader) readTail() error {
	index, n, err := readIndexBody(r.xz)
	if err != nil {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		return err
	}
	if len(index) != len(r.index) {
		return fmt.Errorf("xz: index length is %d; want %d",
			len(index), len(r.index))
	}
	for i, rec := range r.index {
		if rec != index[i] {
			return fmt.Errorf("xz: record %d is %v; want %v",
				i, rec, index[i])
		}
	}

	p := make([]byte, footerLen)
	if _, err = io.ReadFull(r.xz, p); err != nil {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		return err
	}
	var f footer
	if err = f.UnmarshalBinary(p); err != nil {
		return err
	}
	xlog.Debugf("xz footer %s", f)
	if f.flags != r.h.flags {
		return errors.New("xz: footer flags incorrect")
	}
	if f.indexSize != int64(n)+1 {
		return errors.New("xz: index size in footer wrong")
	}
	return nil
}