Add bandwidth counting output stream.
[xudocci.git] / src / main / java / net / pterodactylus / xdcc / util / io / BandwidthCountingOutputStream.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.FilterOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStream;
23 import java.util.concurrent.TimeUnit;
24
25 /**
26  * An {@link OutputStream} that can calculate the bandwidth consumed by its
27  * wrapped output stream.
28  *
29  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
30  */
31 public class BandwidthCountingOutputStream extends FilterOutputStream {
32
33         /** The accumulating data counter. */
34         private final AccumulatingDataCounter accumulatingDataCounter;
35
36         /**
37          * Creates a new bandwidth counting output stream.
38          *
39          * @param outputStream
40          *              The output stream to wrap
41          */
42         public BandwidthCountingOutputStream(OutputStream outputStream) {
43                 super(outputStream);
44                 accumulatingDataCounter = new AccumulatingDataCounter();
45         }
46
47         /**
48          * Creates a new bandwidth counting output stream.
49          *
50          * @param outputStream
51          *              The output 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 BandwidthCountingOutputStream(OutputStream outputStream, long maximumLifeTime, TimeUnit timeUnit) {
58                 super(outputStream);
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 maximum
68          * lifetime of the counter data.
69          *
70          * @return The current rate of this input stream, in bytes/second
71          */
72         public long getCurrentRate() {
73                 return accumulatingDataCounter.getCurrentRate();
74         }
75
76         /**
77          * Returns the current rate of this input stream, averaged over the given
78          * amount of milliseconds.
79          *
80          * @param millis
81          *              The number of millis to average the bandwidth over
82          * @return The current rate of this input stream, in bytes/second
83          */
84         public long getCurrentRate(long millis) {
85                 return accumulatingDataCounter.getCurrentRate(millis);
86         }
87
88         /**
89          * Returns the overall rate of this input stream, averaged over the total
90          * lifetime.
91          *
92          * @return The overall rate of this input stream, in bytes/second
93          */
94         public long getOverallRate() {
95                 return accumulatingDataCounter.getOverallRate();
96         }
97
98         //
99         // OUTPUTSTREAM METHODS
100         //
101
102         @Override
103         public void write(int b) throws IOException {
104                 super.write(b);
105                 accumulatingDataCounter.count(1);
106         }
107
108         @Override
109         public void write(byte[] buffer) throws IOException {
110                 write(buffer, 0, buffer.length);
111         }
112
113         @Override
114         public void write(byte[] buffer, int offset, int length) throws IOException {
115                 super.write(buffer, offset, length);
116                 accumulatingDataCounter.count(length);
117         }
118
119         /**
120          * {@inheritDoc}
121          * <p/>
122          * This method also {@link AccumulatingDataCounter#stop()}s the bandwidth
123          * counter; subsequent calls of {@link #getOverallRate()} will always return
124          * the same value.
125          */
126         @Override
127         public void close() throws IOException {
128                 accumulatingDataCounter.stop();
129                 super.close();
130         }
131
132 }