Add input stream that counts its consumed bandwidth.
[xudocci.git] / src / main / java / net / pterodactylus / xdcc / util / io / BandwidthCountingInputStream.java
1 /*
2  * XdccDownloader - BandwidthCountingInputStream.java - Copyright © 2013 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.xdcc.util.io;
19
20 import java.io.FilterInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.concurrent.TimeUnit;
24
25 /**
26  * An {@link InputStream} that can calculate the bandwidth consumed by its
27  * wrapped input stream.
28  *
29  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
30  */
31 public class BandwidthCountingInputStream extends FilterInputStream {
32
33         /** The accumulating data counter. */
34         private final AccumulatingDataCounter accumulatingDataCounter;
35
36         /**
37          * Creates a new bandwidth counting input stream.
38          *
39          * @param inputStream
40          *              The input stream to wrap
41          */
42         public BandwidthCountingInputStream(InputStream inputStream) {
43                 super(inputStream);
44                 accumulatingDataCounter = new AccumulatingDataCounter();
45         }
46
47         /**
48          * Creates a new bandwidth counting input stream.
49          *
50          * @param inputStream
51          *              The input stream to wrap
52          * @param maximumLifeTime
53          *              The maximum lifetime of the bandwidth counter
54          * @param timeUnit
55          *              The time unit of the lifetime
56          */
57         public BandwidthCountingInputStream(InputStream inputStream, long maximumLifeTime, TimeUnit timeUnit) {
58                 super(inputStream);
59                 accumulatingDataCounter = new AccumulatingDataCounter(maximumLifeTime, timeUnit);
60         }
61
62         //
63         // ACTIONS
64         //
65
66         /**
67          * Returns the current rate of this input stream, averaged over the given
68          * amount of milliseconds.
69          *
70          * @param millis
71          *              The number of millis to average the bandwidth over
72          * @return The current rate of this input stream, in bytes/second
73          */
74         public long getCurrentRate(long millis) {
75                 return accumulatingDataCounter.getCurrentRate(millis);
76         }
77
78         /**
79          * Returns the overall rate of this input stream, averaged over the total
80          * lifetime.
81          *
82          * @return The overall rate of this input stream, in bytes/second
83          */
84         public long getOverallRate() {
85                 return accumulatingDataCounter.getOverallRate();
86         }
87
88         //
89         // INPUTSTREAM METHODS
90         //
91
92         @Override
93         public int read() throws IOException {
94                 int r = super.read();
95                 if (r != -1) {
96                         accumulatingDataCounter.count(1);
97                 }
98                 return r;
99         }
100
101         @Override
102         public int read(byte[] buffer) throws IOException {
103                 return read(buffer, 0, buffer.length);
104         }
105
106         @Override
107         public int read(byte[] buffer, int offset, int length) throws IOException {
108                 int r = super.read(buffer, offset, length);
109                 if (r != -1) {
110                         accumulatingDataCounter.count(r);
111                 }
112                 return r;
113         }
114
115         /**
116          * {@inheritDoc}
117          * <p/>
118          * This method also {@link AccumulatingDataCounter#stop()}s the bandwidth
119          * counter; subsequent calls of {@link #getOverallRate()} will always return
120          * the same value.
121          */
122         @Override
123         public void close() throws IOException {
124                 accumulatingDataCounter.stop();
125                 super.close();
126         }
127
128 }