001/** 002 * Java Web Archive Toolkit - Software to read and validate ARC, WARC 003 * and GZip files. (http://jwat.org/) 004 * Copyright 2011-2012 Netarkivet.dk (http://netarkivet.dk/) 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.jwat.common; 019 020import java.io.FilterInputStream; 021import java.io.IOException; 022import java.io.InputStream; 023 024/** 025 * <code>InputStream</code> that keeps tracks of the number of consumed bytes 026 * at any given time. 027 * 028 * @author lbihanic, selghissassi, nicl 029 */ 030public class ByteCountingInputStream extends FilterInputStream { 031 032 /** Read line initial size. */ 033 public static final int READLINE_INITIAL_SIZE = 128; 034 035 /** Offset relative to beginning of stream. */ 036 protected long consumed = 0; 037 038 /** Byte counter which can also be changed. */ 039 protected long counter = 0; 040 041 /** 042 * Constructs an <code>InputStream</code> that counts the bytes 043 * as it reads them. 044 * @param in InputStream to wrap 045 */ 046 public ByteCountingInputStream(InputStream in) { 047 super(in); 048 } 049 050 /** 051 * Retrieve the number of bytes consumed by this stream. 052 * @return current byte offset in this stream 053 */ 054 public long getConsumed() { 055 return consumed; 056 } 057 058 /** 059 * Change the counter value. 060 * Useful for reading zero indexed relative data. 061 * @param bytes new counter value 062 */ 063 public void setCounter(long bytes) { 064 counter = bytes; 065 } 066 067 /** 068 * Retrieve the current counter value. 069 * @return current counter value 070 */ 071 public long getCounter() { 072 return counter; 073 } 074 075 @Override 076 public boolean markSupported() { 077 return false; 078 } 079 080 @Override 081 public synchronized void mark(int readlimit) { 082 } 083 084 @Override 085 public synchronized void reset() throws IOException { 086 throw new UnsupportedOperationException(); 087 } 088 089 @Override 090 public int read() throws IOException { 091 int b = in.read(); 092 if (b != -1) { 093 ++consumed; 094 ++counter; 095 } 096 return b; 097 } 098 099 @Override 100 public int read(byte[] b, int off, int len) throws IOException { 101 int bytesRead = in.read(b, off, len); 102 if (bytesRead > 0) { 103 consumed += bytesRead; 104 counter += bytesRead; 105 } 106 return bytesRead; 107 } 108 109 @Override 110 public long skip(long n) throws IOException { 111 long bytesSkipped = in.skip(n); 112 consumed += bytesSkipped; 113 counter += bytesSkipped; 114 return bytesSkipped; 115 } 116 117}