--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.services.io.LimitInputStream\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.services.io;\r
+\r
+import java.io.InputStream;\r
+import java.io.FilterInputStream;\r
+import java.io.IOException;\r
+\r
+/**\r
+ An abstract InputStream that provides abstract methods to limit the range that\r
+ can be read from the stream.\r
+*/\r
+public class LimitInputStream extends FilterInputStream implements Limit {\r
+\r
+ protected int remainingBytes;\r
+ protected boolean limitInPlace;\r
+\r
+ /**\r
+ Construct a LimitInputStream and call the clearLimit() method.\r
+ */\r
+ public LimitInputStream(InputStream in) {\r
+ super(in);\r
+ clearLimit();\r
+ }\r
+\r
+ public int read() throws IOException {\r
+\r
+ if (!limitInPlace)\r
+ return super.read();\r
+ \r
+ if (remainingBytes == 0)\r
+ return -1; // end of file\r
+\r
+ \r
+ int value = super.read();\r
+ if (value >= 0)\r
+ remainingBytes--;\r
+ return value;\r
+\r
+ }\r
+\r
+ public int read(byte b[], int off, int len) throws IOException {\r
+\r
+ if (!limitInPlace)\r
+ return super.read(b, off, len);\r
+\r
+\r
+ if (remainingBytes == 0)\r
+ return -1;\r
+\r
+ if (remainingBytes < len) {\r
+ len = remainingBytes; // end of file\r
+ }\r
+\r
+ len = super.read(b, off, len);\r
+ if (len > 0)\r
+ remainingBytes -= len;\r
+\r
+ return len;\r
+ }\r
+\r
+ public long skip(long count) throws IOException {\r
+ if (!limitInPlace)\r
+ return super.skip(count);\r
+\r
+ if (remainingBytes == 0)\r
+ return 0; // end of file\r
+\r
+ if (remainingBytes < count)\r
+ count = remainingBytes;\r
+\r
+ count = super.skip(count);\r
+ remainingBytes -= count;\r
+ return count;\r
+ }\r
+\r
+ public int available() throws IOException {\r
+\r
+ if (!limitInPlace)\r
+ return super.available();\r
+\r
+ if (remainingBytes == 0)\r
+ return 0; // end of file\r
+\r
+ int actualLeft = super.available();\r
+\r
+ if (remainingBytes < actualLeft)\r
+ return remainingBytes;\r
+ \r
+\r
+ return actualLeft;\r
+ }\r
+\r
+\r
+ /**\r
+ Set the limit of the stream that can be read. After this\r
+ call up to and including length bytes can be read from or skipped in\r
+ the stream. Any attempt to read more than length bytes will\r
+ result in an EOFException\r
+\r
+ @exception IOException IOException from some underlying stream\r
+ @exception EOFException The set limit would exceed\r
+ the available data in the stream.\r
+ */\r
+ public void setLimit(int length) {\r
+ remainingBytes = length;\r
+ limitInPlace = true;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ Clear any limit set by setLimit. After this call no limit checking\r
+ will be made on any read until a setLimit()) call is made.\r
+\r
+ @return the number of bytes within the limit that have not been read.\r
+ -1 if no limit was set.\r
+ */\r
+ public int clearLimit() {\r
+ int leftOver = remainingBytes;\r
+ limitInPlace = false;\r
+ remainingBytes = -1;\r
+ return leftOver;\r
+ }\r
+\r
+ public void setInput(InputStream in) {\r
+ this.in = in;\r
+ }\r
+}\r