001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.vfs.util;
018:
019: import java.io.BufferedInputStream;
020: import java.io.IOException;
021: import java.io.InputStream;
022:
023: /**
024: * An InputStream that provides buffering and end-of-stream monitoring.
025: *
026: * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
027: * @version $Revision: 501759 $ $Date: 2007-01-31 00:07:57 -0800 (Wed, 31 Jan 2007) $
028: */
029: public class MonitorInputStream extends BufferedInputStream {
030: private boolean finished;
031: private long count;
032:
033: public MonitorInputStream(final InputStream in) {
034: super (in);
035: count = 0;
036: }
037:
038: /**
039: * Returns 0 if the stream is at eof, else the underlaying inputStream will be queried
040: */
041: public synchronized int available() throws IOException {
042: if (finished) {
043: return 0;
044: }
045:
046: return super .available();
047: }
048:
049: /**
050: * Reads a character.
051: */
052: public int read() throws IOException {
053: if (finished) {
054: return -1;
055: }
056:
057: final int ch = super .read();
058: if (ch != -1) {
059: count++;
060: return ch;
061: }
062:
063: // End-of-stream
064: close();
065: return -1;
066: }
067:
068: /**
069: * Reads bytes from this input stream.error occurs.
070: */
071: public int read(final byte[] buffer, final int offset,
072: final int length) throws IOException {
073: if (finished) {
074: return -1;
075: }
076:
077: final int nread = super .read(buffer, offset, length);
078: if (nread != -1) {
079: count += nread;
080: return nread;
081: }
082:
083: // End-of-stream
084: close();
085: return -1;
086: }
087:
088: /**
089: * Closes this input stream and releases any system resources
090: * associated with the stream.
091: */
092: public void close() throws IOException {
093: if (finished) {
094: return;
095: }
096:
097: // Close the stream
098: IOException exc = null;
099: try {
100: super .close();
101: } catch (final IOException ioe) {
102: exc = ioe;
103: }
104:
105: // Notify that the stream has been closed
106: try {
107: onClose();
108: } catch (final IOException ioe) {
109: exc = ioe;
110: }
111:
112: finished = true;
113: if (exc != null) {
114: throw exc;
115: }
116: }
117:
118: /**
119: * Called after the stream has been closed. This implementation does
120: * nothing.
121: */
122: protected void onClose() throws IOException {
123: }
124:
125: /**
126: * Get the nuber of bytes read by this input stream
127: */
128: public long getCount() {
129: return count;
130: }
131: }
|