View Javadoc

1   /* SafeSeekInputStream
2   *
3   * Created on September 14, 2006
4   *
5   * Copyright (C) 2006 Internet Archive.
6   *
7   * This file is part of the Heritrix web crawler (crawler.archive.org).
8   *
9   * Heritrix is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * any later version.
13  *
14  * Heritrix is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser Public License
20  * along with Heritrix; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23  package org.archive.io;
24  
25  
26  import java.io.IOException;
27  
28  
29  /***
30   * Enables multiple concurrent streams based on the same underlying stream.
31   * 
32   * @author pjack
33   */
34  public class SafeSeekInputStream extends SeekInputStream {
35  
36  
37      /***
38       * The underlying stream.
39       */
40      private SeekInputStream input;
41  
42  
43      /***
44       * The expected position of the underlying stream.
45       */
46      private long expected;
47  
48  
49      /***
50       * Constructor.  The given stream will be positioned to 0 so that an
51       * accurate position can be tracked.
52       * 
53       * @param input  the underlying input stream
54       * @throws IOException   if an IO error occurs
55       */
56      public SafeSeekInputStream(SeekInputStream input) throws IOException {
57          this.input = input;
58          this.expected = input.position();
59      }
60  
61  
62      /***
63       * Ensures that the underlying stream's position is what we expect to be.
64       * 
65       * @throws IOException  if an IO error occurs
66       */
67      private void ensure() throws IOException {
68          if (expected != input.position()) {
69              input.position(expected);
70          }
71      }
72  
73  
74      @Override
75      public int read() throws IOException {
76          ensure();
77          int c = input.read();
78          if (c >= 0) {
79              expected++;
80          }
81          return c;
82      }
83  
84  
85      @Override
86      public int read(byte[] buf, int ofs, int len) throws IOException {
87          ensure();
88          int r = input.read(buf, ofs, len);
89          if (r > 0) {
90              expected += r;
91          }
92          return r;
93      }
94  
95  
96      @Override
97      public int read(byte[] buf) throws IOException {
98          ensure();
99          int r = input.read(buf);
100         if (r > 0) {
101             expected += r;
102         }
103         return r;
104     }
105 
106 
107     @Override
108     public long skip(long c) throws IOException {
109         ensure();
110         long r = input.skip(c);
111         if (r > 0) {
112             expected += r;
113         }
114         return r;
115     }
116     
117     
118     public void position(long p) throws IOException {
119         input.position(p);
120         expected = p;
121     }
122 
123 
124     public long position() throws IOException {
125         return expected;
126     }
127 
128 }