001: /*
002:
003: Derby - Class org.apache.derby.iapi.services.io.LimitInputStream
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.services.io;
023:
024: import java.io.InputStream;
025: import java.io.FilterInputStream;
026: import java.io.IOException;
027:
028: /**
029: An abstract InputStream that provides abstract methods to limit the range that
030: can be read from the stream.
031: */
032: public class LimitInputStream extends FilterInputStream implements
033: Limit {
034:
035: protected int remainingBytes;
036: protected boolean limitInPlace;
037:
038: /**
039: Construct a LimitInputStream and call the clearLimit() method.
040: */
041: public LimitInputStream(InputStream in) {
042: super (in);
043: clearLimit();
044: }
045:
046: public int read() throws IOException {
047:
048: if (!limitInPlace)
049: return super .read();
050:
051: if (remainingBytes == 0)
052: return -1; // end of file
053:
054: int value = super .read();
055: if (value >= 0)
056: remainingBytes--;
057: return value;
058:
059: }
060:
061: public int read(byte b[], int off, int len) throws IOException {
062:
063: if (!limitInPlace)
064: return super .read(b, off, len);
065:
066: if (remainingBytes == 0)
067: return -1;
068:
069: if (remainingBytes < len) {
070: len = remainingBytes; // end of file
071: }
072:
073: len = super .read(b, off, len);
074: if (len > 0)
075: remainingBytes -= len;
076:
077: return len;
078: }
079:
080: public long skip(long count) throws IOException {
081: if (!limitInPlace)
082: return super .skip(count);
083:
084: if (remainingBytes == 0)
085: return 0; // end of file
086:
087: if (remainingBytes < count)
088: count = remainingBytes;
089:
090: count = super .skip(count);
091: remainingBytes -= count;
092: return count;
093: }
094:
095: public int available() throws IOException {
096:
097: if (!limitInPlace)
098: return super .available();
099:
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: return actualLeft;
109: }
110:
111: /**
112: Set the limit of the stream that can be read. After this
113: call up to and including length bytes can be read from or skipped in
114: the stream. Any attempt to read more than length bytes will
115: result in an EOFException
116:
117: @exception IOException IOException from some underlying stream
118: @exception EOFException The set limit would exceed
119: the available data in the stream.
120: */
121: public void setLimit(int length) {
122: remainingBytes = length;
123: limitInPlace = true;
124: return;
125: }
126:
127: /**
128: Clear any limit set by setLimit. After this call no limit checking
129: will be made on any read until a setLimit()) call is made.
130:
131: @return the number of bytes within the limit that have not been read.
132: -1 if no limit was set.
133: */
134: public int clearLimit() {
135: int leftOver = remainingBytes;
136: limitInPlace = false;
137: remainingBytes = -1;
138: return leftOver;
139: }
140:
141: public void setInput(InputStream in) {
142: this.in = in;
143: }
144: }
|