// readFilter reads a block filter from the block header. At this point // in time only the LZMA2 filter is supported. func readFilter(r io.Reader) (f filter, err error) { br := lzma.ByteReader(r) // index id, _, err := readUvarint(br) if err != nil { return nil, err } var data []byte switch id { case lzmaFilterID: data = make([]byte, lzmaFilterLen) data[0] = lzmaFilterID if _, err = io.ReadFull(r, data[1:]); err != nil { return nil, err } f = new(lzmaFilter) default: if id >= minReservedID { return nil, errors.New( "xz: reserved filter id in block stream header") } return nil, errors.New("xz: invalid filter id") } if err = f.UnmarshalBinary(data); err != nil { return nil, err } return f, err }
// readIndexBody reads the index from the reader. It assumes that the // index indicator has already been read. func readIndexBody(r io.Reader) (records []record, n int64, err error) { crc := crc32.NewIEEE() // index indicator crc.Write([]byte{0}) br := lzma.ByteReader(io.TeeReader(r, crc)) // number of records u, k, err := readUvarint(br) n += int64(k) if err != nil { return nil, n, err } recLen := int(u) if recLen < 0 || uint64(recLen) != u { return nil, n, errors.New("xz: record number overflow") } // list of records records = make([]record, recLen) for i := range records { records[i], k, err = readRecord(br) n += int64(k) if err != nil { return nil, n, err } } p := make([]byte, padLen(int64(n+1)), 4) k, err = io.ReadFull(br.(io.Reader), p) n += int64(k) if err != nil { return nil, n, err } if !allZeros(p) { return nil, n, errors.New("xz: non-zero byte in index padding") } // crc32 s := crc.Sum32() p = p[:4] k, err = io.ReadFull(br.(io.Reader), p) n += int64(k) if err != nil { return records, n, err } if uint32LE(p) != s { return nil, n, errors.New("xz: wrong checksum for index") } return records, n, nil }