View Javadoc

1   /*
2    * Copyright (c) 2004-2007 Creative Sphere Limited.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *
10   *   Creative Sphere - initial API and implementation
11   *
12   */
13  package org.abstracthorizon.mercury.common.io;
14  
15  import java.io.IOException;
16  import java.io.InputStream;
17  
18  
19  /**
20   * Input stream that returns only a defined range
21   *
22   * @author Daniel Sendula
23   */
24  public class RangedInputStream extends InputStream {
25  
26      /** Underlying input stream */
27      protected InputStream is;
28  
29      /** Starting offset */
30      protected long from;
31  
32      /** End offset */
33      protected long to;
34  
35      /** Number of bytes left to be read */
36      protected long left;
37  
38      /** Mark */
39      protected long marked;
40  
41      /** Read limit */
42      protected long readlimit;
43  
44      /** Read limit cache */
45      protected long readlimitCache;
46  
47      /**
48       * Constructor
49       * @param is input stream
50       * @param from from offset
51       * @param to to offset
52       * @throws IOException
53       */
54      public RangedInputStream(InputStream is, long from, long to) throws IOException {
55          this.is = is;
56          this.from = from;
57          this.to = to;
58          long l = is.skip(from);
59          if (l < from) {
60              left = 0;
61          } else {
62              left = to-from;
63          }
64          readlimit = -1;
65          readlimitCache = -1;
66      }
67  
68      @Override
69      public int available() throws IOException {
70          int i = is.available();
71          if (i > left) {
72              i = (int)left;
73          }
74          return i;
75      }
76  
77      @Override
78      public void close() throws IOException {
79          is.close();
80      }
81  
82      @Override
83      public void mark(int readlimit) {
84          is.mark(readlimit);
85          this.readlimit = readlimit;
86          this.readlimitCache = readlimit;
87          marked = left;
88      }
89  
90      @Override
91      public boolean markSupported() {
92          return is.markSupported();
93      }
94  
95      @Override
96      public int read() throws IOException {
97          if (left == 0) {
98              return -1;
99          }
100         int i = is.read();
101         if (i >= 0) {
102             left = left-1;
103             if (readlimit >= 0) {
104                 readlimit = readlimit-1;
105                 if (readlimit < 0) {
106                     readlimitCache = -1;
107                 }
108             }
109         }
110         return i;
111     }
112 
113     @Override
114     public int read(byte[] b) throws IOException {
115         if (left == 0) {
116             return -1;
117         }
118         if (left < b.length) {
119             return read(b, 0, (int)left);
120         }
121         int i = is.read(b);
122         if (i >= 0) {
123             left = left - i;
124             if (readlimit >= 0) {
125                 readlimit = readlimit-i;
126                 if (readlimit < 0) {
127                     readlimitCache = -1;
128                 }
129             }
130         } else {
131             left = 0;
132         }
133         return i;
134     }
135 
136     @Override
137     public int read(byte[] b, int off, int len) throws IOException {
138         if (left == 0) {
139             return -1;
140         }
141         if (left < len) {
142             len = (int)left;
143         }
144         int i = is.read(b, off, len);
145         if (i >= 0) {
146             left = left - i;
147             if (readlimit >= 0) {
148                 readlimit = readlimit-i;
149                 if (readlimit < 0) {
150                     readlimitCache = -1;
151                 }
152             }
153         } else {
154             left = 0;
155         }
156         return i;
157     }
158 
159     @Override
160     public void reset() throws IOException {
161         is.reset();
162         if (readlimit >= 0) {
163             left = marked;
164             readlimit = readlimitCache;
165         }
166     }
167 
168     @Override
169     public long skip(long n) throws IOException {
170         if (left == 0) {
171             return 0;
172         }
173         if (n > left) {
174             n = left;
175         }
176         long i = is.skip(n);
177         left = left - i;
178         return i;
179     }
180 }