1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Licensed under the Apache License, Version 2.0 (the "License"); 5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * you may not use this file except in compliance with the License. 6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * You may obtain a copy of the License at 7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * http://www.apache.org/licenses/LICENSE-2.0 9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Unless required by applicable law or agreed to in writing, software 11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * distributed under the License is distributed on an "AS IS" BASIS, 12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * See the License for the specific language governing permissions and 14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * limitations under the License. 15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpackage com.google.common.io; 18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.FilterInputStream; 22bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.IOException; 23bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.InputStream; 24bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 25bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/** 26bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * An {@link InputStream} that counts the number of bytes read. 27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 28bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Chris Nokleberg 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0 30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class CountingInputStream extends FilterInputStream { 33bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 34bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private long count; 35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private long mark = -1; 36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Wraps another input stream, counting the number of bytes read. 39bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 40bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param in the input stream to be wrapped 41bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public CountingInputStream(InputStream in) { 43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor super(in); 44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 45bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 46bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** Returns the number of bytes read. */ 47bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public long getCount() { 48bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return count; 49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 50bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 51bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor @Override public int read() throws IOException { 52bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int result = in.read(); 53bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (result != -1) { 54bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count++; 55bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 56bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 57bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 59bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor @Override public int read(byte[] b, int off, int len) throws IOException { 60bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int result = in.read(b, off, len); 61bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (result != -1) { 62bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count += result; 63bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 64bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 65bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor @Override public long skip(long n) throws IOException { 68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long result = in.skip(n); 69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count += result; 70bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 71bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 72bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public synchronized void mark(int readlimit) { 74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor in.mark(readlimit); 75bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor mark = count; 76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // it's okay to mark even if mark isn't supported, as reset won't work 77bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 78bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public synchronized void reset() throws IOException { 80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (!in.markSupported()) { 81bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IOException("Mark not supported"); 82bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 83bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (mark == -1) { 84bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IOException("Mark not set"); 85bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 86bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 87bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor in.reset(); 88bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count = mark; 89bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor} 91