1 | /* |
2 | |
3 | Derby - Class org.apache.derby.iapi.services.io.LimitInputStream |
4 | |
5 | Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.iapi.services.io; |
22 | |
23 | import java.io.InputStream; |
24 | import java.io.FilterInputStream; |
25 | import java.io.IOException; |
26 | |
27 | /** |
28 | An abstract InputStream that provides abstract methods to limit the range that |
29 | can be read from the stream. |
30 | */ |
31 | public class LimitInputStream extends FilterInputStream implements Limit { |
32 | |
33 | protected int remainingBytes; |
34 | protected boolean limitInPlace; |
35 | |
36 | /** |
37 | Construct a LimitInputStream and call the clearLimit() method. |
38 | */ |
39 | public LimitInputStream(InputStream in) { |
40 | super(in); |
41 | clearLimit(); |
42 | } |
43 | |
44 | public int read() throws IOException { |
45 | |
46 | if (!limitInPlace) |
47 | return super.read(); |
48 | |
49 | if (remainingBytes == 0) |
50 | return -1; // end of file |
51 | |
52 | |
53 | int value = super.read(); |
54 | if (value >= 0) |
55 | remainingBytes--; |
56 | return value; |
57 | |
58 | } |
59 | |
60 | public int read(byte b[], int off, int len) throws IOException { |
61 | |
62 | if (!limitInPlace) |
63 | return super.read(b, off, len); |
64 | |
65 | |
66 | if (remainingBytes == 0) |
67 | return -1; |
68 | |
69 | if (remainingBytes < len) { |
70 | len = remainingBytes; // end of file |
71 | } |
72 | |
73 | len = super.read(b, off, len); |
74 | if (len > 0) |
75 | remainingBytes -= len; |
76 | |
77 | return len; |
78 | } |
79 | |
80 | public long skip(long count) throws IOException { |
81 | if (!limitInPlace) |
82 | return super.skip(count); |
83 | |
84 | if (remainingBytes == 0) |
85 | return 0; // end of file |
86 | |
87 | if (remainingBytes < count) |
88 | count = remainingBytes; |
89 | |
90 | count = super.skip(count); |
91 | remainingBytes -= count; |
92 | return count; |
93 | } |
94 | |
95 | public int available() throws IOException { |
96 | |
97 | if (!limitInPlace) |
98 | return super.available(); |
99 | |
100 | if (remainingBytes == 0) |
101 | return 0; // end of file |
102 | |
103 | int actualLeft = super.available(); |
104 | |
105 | if (remainingBytes < actualLeft) |
106 | return remainingBytes; |
107 | |
108 | |
109 | return actualLeft; |
110 | } |
111 | |
112 | |
113 | /** |
114 | Set the limit of the stream that can be read. After this |
115 | call up to and including length bytes can be read from or skipped in |
116 | the stream. Any attempt to read more than length bytes will |
117 | result in an EOFException |
118 | |
119 | @exception IOException IOException from some underlying stream |
120 | @exception EOFException The set limit would exceed |
121 | the available data in the stream. |
122 | */ |
123 | public void setLimit(int length) { |
124 | remainingBytes = length; |
125 | limitInPlace = true; |
126 | return; |
127 | } |
128 | |
129 | /** |
130 | Clear any limit set by setLimit. After this call no limit checking |
131 | will be made on any read until a setLimit()) call is made. |
132 | |
133 | @return the number of bytes within the limit that have not been read. |
134 | -1 if no limit was set. |
135 | */ |
136 | public int clearLimit() { |
137 | int leftOver = remainingBytes; |
138 | limitInPlace = false; |
139 | remainingBytes = -1; |
140 | return leftOver; |
141 | } |
142 | |
143 | public void setInput(InputStream in) { |
144 | this.in = in; |
145 | } |
146 | } |