1/*
2 * XZSeekDecDemo
3 *
4 * Author: Lasse Collin <lasse.collin@tukaani.org>
5 *
6 * This file has been put into the public domain.
7 * You can do whatever you want with this file.
8 */
9
10import java.io.*;
11import org.tukaani.xz.*;
12
13/**
14 * Decompresses a .xz file in random access mode to standard output.
15 * <p>
16 * Arguments: filename [offset1 length1] [offset2 length2] ...
17 * <p>
18 * If only the filename is given, the whole file is decompressed. The only
19 * difference to XZDecDemo is that this will still use the random access code.
20 * <p>
21 * If one or more of the offset-length pairs are given,
22 * for each pair, <code>length</code> number of bytes are
23 * decompressed from <code>offset</code>.
24 */
25class XZSeekDecDemo {
26    public static void main(String[] args) throws Exception {
27        SeekableFileInputStream file = new SeekableFileInputStream(args[0]);
28        SeekableXZInputStream in = new SeekableXZInputStream(file);
29
30        System.err.println("Number of XZ Streams: " + in.getStreamCount());
31        System.err.println("Number of XZ Blocks: " + in.getBlockCount());
32
33        System.err.println("Uncompressed size: " + in.length() + " B");
34
35        System.err.println("Largest XZ Block size: "
36                           + in.getLargestBlockSize() + " B");
37
38        System.err.print("List of Check IDs:");
39        int checkTypes = in.getCheckTypes();
40        for (int i = 0; i < 16; ++i)
41            if ((checkTypes & (1 << i)) != 0)
42                System.err.print(" " + i);
43        System.err.println();
44
45        System.err.println("Index memory usage: "
46                           + in.getIndexMemoryUsage() + " KiB");
47
48        byte[] buf = new byte[8192];
49        if (args.length == 1) {
50            int size;
51            while ((size = in.read(buf)) != -1)
52                System.out.write(buf, 0, size);
53        } else {
54            for (int i = 1; i < args.length; i += 2) {
55                int pos = Integer.parseInt(args[i]);
56                int len = Integer.parseInt(args[i + 1]);
57
58                in.seek(pos);
59
60                while (len > 0) {
61                    int size = Math.min(len, buf.length);
62                    size = in.read(buf, 0, size);
63
64                    if (size == -1) {
65                        System.err.println("Error: End of file reached");
66                        System.exit(1);
67                    }
68
69                    System.out.write(buf, 0, size);
70                    len -= size;
71                }
72            }
73        }
74    }
75}
76