1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.archive.io;
24
25
26 import java.io.IOException;
27
28
29 /***
30 * Alters the origin of some other SeekInputStream. This class allows you
31 * to completely ignore everything in the underlying stream before a specified
32 * position, the origin position.
33 *
34 * <p>With the exception of {@link #position()} and {@link position(long)},
35 * all of the methods in this class simply delegate to the underlying input
36 * stream. The <code>position</code> methods adjust the position of the
37 * underlying stream relative to the origin specified at construction time.
38 *
39 * @author pjack
40 */
41 public class OriginSeekInputStream extends SeekInputStream {
42
43
44 /***
45 * The underlying stream.
46 */
47 final private SeekInputStream input;
48
49
50 /***
51 * The origin position. In other words, this.position(0)
52 * resolves to input.position(start).
53 */
54 final private long origin;
55
56
57 /***
58 * Constructor.
59 *
60 * @param input the underlying stream
61 * @param origin the origin position
62 * @throws IOException if an IO error occurs
63 */
64 public OriginSeekInputStream(SeekInputStream input, long origin)
65 throws IOException {
66 this.input = input;
67 this.origin = origin;
68 input.position(origin);
69 }
70
71
72 @Override
73 public int available() throws IOException {
74 return input.available();
75 }
76
77
78 @Override
79 public int read() throws IOException {
80 return input.read();
81 }
82
83
84 @Override
85 public int read(byte[] buf, int ofs, int len) throws IOException {
86 return input.read(buf, ofs, len);
87 }
88
89
90 @Override
91 public int read(byte[] buf) throws IOException {
92 return input.read(buf);
93 }
94
95
96 @Override
97 public long skip(long count) throws IOException {
98 return input.skip(count);
99 }
100
101
102 /***
103 * Returns the position of the underlying stream relative to the origin.
104 *
105 * @return the relative position
106 * @throws IOException if an IO error occurs
107 */
108 public long position() throws IOException {
109 return input.position() - origin;
110 }
111
112
113 /***
114 * Positions the underlying stream relative to the origin.
115 * In other words, this.position(0) resolves to input.position(origin),
116 * where input is underlying stream and origin is the origin specified
117 * at construction time.
118 *
119 * @param p the new position for this stream
120 * @throws IOException if an IO error occurs
121 */
122 public void position(long p) throws IOException {
123 input.position(p + origin);
124 }
125 }