001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.io; 018 019import com.google.common.annotations.Beta; 020import com.google.common.base.Preconditions; 021 022import java.io.FilterInputStream; 023import java.io.IOException; 024import java.io.InputStream; 025 026/** 027 * An InputStream that limits the number of bytes which can be read. 028 * 029 * @author Charles Fry 030 * @since 1.0 031 * @deprecated Use {@link ByteStreams#limit} instead. This class is scheduled 032 * to be removed in Guava release 15.0. 033 */ 034@Beta 035@Deprecated 036public final class LimitInputStream extends FilterInputStream { 037 038 private long left; 039 private long mark = -1; 040 041 /** 042 * Wraps another input stream, limiting the number of bytes which can be read. 043 * 044 * @param in the input stream to be wrapped 045 * @param limit the maximum number of bytes to be read 046 */ 047 public LimitInputStream(InputStream in, long limit) { 048 super(in); 049 Preconditions.checkNotNull(in); 050 Preconditions.checkArgument(limit >= 0, "limit must be non-negative"); 051 left = limit; 052 } 053 054 @Override public int available() throws IOException { 055 return (int) Math.min(in.available(), left); 056 } 057 058 @Override public synchronized void mark(int readlimit) { 059 in.mark(readlimit); 060 mark = left; 061 // it's okay to mark even if mark isn't supported, as reset won't work 062 } 063 064 @Override public int read() throws IOException { 065 if (left == 0) { 066 return -1; 067 } 068 069 int result = in.read(); 070 if (result != -1) { 071 --left; 072 } 073 return result; 074 } 075 076 @Override public int read(byte[] b, int off, int len) throws IOException { 077 if (left == 0) { 078 return -1; 079 } 080 081 len = (int) Math.min(len, left); 082 int result = in.read(b, off, len); 083 if (result != -1) { 084 left -= result; 085 } 086 return result; 087 } 088 089 @Override public synchronized void reset() throws IOException { 090 if (!in.markSupported()) { 091 throw new IOException("Mark not supported"); 092 } 093 if (mark == -1) { 094 throw new IOException("Mark not set"); 095 } 096 097 in.reset(); 098 left = mark; 099 } 100 101 @Override public long skip(long n) throws IOException { 102 n = Math.min(n, left); 103 long skipped = in.skip(n); 104 left -= skipped; 105 return skipped; 106 } 107}