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 257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport javax.annotation.Nullable; 267dd252788645e940eada959bdde927426e2531c9Paul Duffin 27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/** 28bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * An {@link InputStream} that counts the number of bytes read. 29bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Chris Nokleberg 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0 32bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class CountingInputStream extends FilterInputStream { 35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private long count; 37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private long mark = -1; 38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 39bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 40bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Wraps another input stream, counting the number of bytes read. 41bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param in the input stream to be wrapped 43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 447dd252788645e940eada959bdde927426e2531c9Paul Duffin public CountingInputStream(@Nullable InputStream in) { 45bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor super(in); 46bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 47bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 48bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** Returns the number of bytes read. */ 49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public long getCount() { 50bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return count; 51bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 52bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 530888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int read() throws IOException { 54bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int result = in.read(); 55bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (result != -1) { 56bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count++; 57bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 59bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 60bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 610888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int read(byte[] b, int off, int len) throws IOException { 62bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int result = in.read(b, off, len); 63bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (result != -1) { 64bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count += result; 65bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 690888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public long skip(long n) throws IOException { 70bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long result = in.skip(n); 71bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count += result; 72bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 750888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public synchronized void mark(int readlimit) { 76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor in.mark(readlimit); 77bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor mark = count; 78bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // it's okay to mark even if mark isn't supported, as reset won't work 79bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 810888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public synchronized void reset() throws IOException { 82bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (!in.markSupported()) { 83bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IOException("Mark not supported"); 84bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 85bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (mark == -1) { 86bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IOException("Mark not set"); 87bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 88bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 89bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor in.reset(); 90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count = mark; 91bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 92bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor} 93