001: /*
002:
003: Derby - Class org.apache.derby.iapi.services.io.LimitReader
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.Reader;
025: import java.io.IOException;
026:
027: /**
028: A Reader that provides methods to limit the range that
029: can be read from the reader.
030: */
031: public final class LimitReader extends Reader implements Limit {
032: private int remainingCharacters;
033: private boolean limitInPlace;
034: private Reader reader;
035:
036: /**
037: Construct a LimitReader and call the clearLimit() method.
038: */
039: public LimitReader(Reader reader) {
040: super ();
041: this .reader = reader;
042: clearLimit();
043: }
044:
045: public int read() throws IOException {
046:
047: if (!limitInPlace)
048: return reader.read();
049:
050: if (remainingCharacters == 0)
051: return -1; // end of file
052:
053: int value = reader.read();
054: if (value >= 0)
055: remainingCharacters--;
056: return value;
057:
058: }
059:
060: public int read(char c[], int off, int len) throws IOException {
061: if (!limitInPlace)
062: return reader.read(c, off, len);
063:
064: if (remainingCharacters == 0)
065: return -1;
066:
067: if (remainingCharacters < len) {
068: len = remainingCharacters; // end of file
069: }
070:
071: len = reader.read(c, off, len);
072: if (len >= 0)
073: remainingCharacters -= len;
074: return len;
075: }
076:
077: public long skip(long count) throws IOException {
078: if (!limitInPlace)
079: return reader.skip(count);
080:
081: if (remainingCharacters == 0)
082: return 0; // end of file
083:
084: if (remainingCharacters < count)
085: count = remainingCharacters;
086:
087: count = reader.skip(count);
088: remainingCharacters -= count;
089: return count;
090: }
091:
092: public void close() throws IOException {
093: reader.close();
094: }
095:
096: /**
097: Set the limit of the stream that can be read. After this
098: call up to and including length characters can be read from
099: or skipped in the stream.
100: Any attempt to read more than length characters will
101: result in an EOFException
102:
103: @exception IOException IOException from some underlying stream
104: @exception EOFException The set limit would exceed
105: the available data in the stream.
106: */
107: public void setLimit(int length) {
108: remainingCharacters = length;
109: limitInPlace = true;
110: return;
111: }
112:
113: /**
114: * return limit of the stream that can be read without throwing
115: * EOFException
116: * @return the remaining characters left to be read from the stream
117: */
118: public final int getLimit() {
119: return remainingCharacters;
120: }
121:
122: /**
123: Clear any limit set by setLimit. After this call no limit checking
124: will be made on any read until a setLimit()) call is made.
125:
126: @return the number of bytes within the limit that have not been read.
127: -1 if not limit was set.
128: */
129: public int clearLimit() {
130: int leftOver = remainingCharacters;
131: limitInPlace = false;
132: remainingCharacters = -1;
133: return leftOver;
134: }
135: }
|