func main() { dec, er := xz.NewReader(os.Stdin) if er != nil { fmt.Println(er) os.Exit(1) } io.Copy(os.Stdout, dec) }
func OpenPackage(name string) (x ReadCloser, err error) { f, err := os.Open(name) if err != nil { return x, err } var rd io.ReadCloser switch filepath.Ext(name) { case ".xz": rd, err = xz.NewReader(f) case ".gz": rd, err = gzip.NewReader(f) default: return x, fmt.Errorf("not a package name: %s", name) } if err != nil { f.Close() return x, err } return ReadCloser{rd, []io.Closer{rd, f}}, nil }
// return the uncompressed data associated with this article func (a *Article) Data() ([]byte, error) { // ensure we have data to read if a.EntryType == RedirectEntry || a.EntryType == LinkTargetEntry || a.EntryType == DeletedEntry { return nil, nil } start, end, err := a.z.clusterOffsetsAtIdx(a.cluster) if err != nil { return nil, err } s, err := a.z.bytesRangeAt(start, start+1) if err != nil { return nil, err } compression := uint8(s[0]) // blob starts at offset, blob ends at offset var bs, be uint32 // LZMA if compression == 4 { b, err := a.z.bytesRangeAt(start+1, end+1) if err != nil { return nil, err } bbuf := bytes.NewBuffer(b) dec, err := xz.NewReader(bbuf) defer dec.Close() if err != nil { return nil, err } // the decoded chunk are around 1MB // TODO: on smaller devices need to read stream rather than ReadAll blob, err := ioutil.ReadAll(dec) if err != nil { return nil, err } bs, err = readInt32(blob[a.blob*4:a.blob*4+4], nil) if err != nil { return nil, err } be, err = readInt32(blob[a.blob*4+4:a.blob*4+4+4], nil) if err != nil { return nil, err } // avoid retaining all the chunk c := make([]byte, be-bs) copy(c, blob[bs:be]) return c, nil } else if compression == 0 || compression == 1 { // un compresssed startPos := start + 1 blobOffset := uint64(a.blob * 4) bs, err := readInt32(a.z.bytesRangeAt(startPos+blobOffset, startPos+blobOffset+4)) if err != nil { return nil, err } be, err := readInt32(a.z.bytesRangeAt(startPos+blobOffset+4, startPos+blobOffset+4+4)) if err != nil { return nil, err } return a.z.bytesRangeAt(startPos+uint64(bs), startPos+uint64(be)) } return nil, errors.New("Unhandled compression") }
func (c *XZDecompressor) NewReader(src io.Reader) (io.Reader, error) { return xz.NewReader(src) }