package net.i2p.router.transport;
/*
 * free (adj.): unencumbered; not under the control of others
 * Written by jrandom in 2003 and released into the public domain
 * with no warranty of any kind, either expressed or implied.
 * It probably won't make your computer catch on fire, or eat
 * your children, but it might.  Use at your own risk.
 *
 */

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import net.i2p.data.RouterIdentity;
import net.i2p.router.RouterContext;

public class BandwidthLimitedInputStream extends FilterInputStream {
    private RouterIdentity _peer;
    private RouterContext _context;
    public BandwidthLimitedInputStream(RouterContext context, InputStream source, RouterIdentity peer) {
        super(source);
        _context = context;
        _peer = peer;
    }
    
    public int read() throws IOException {
        _context.bandwidthLimiter().delayInbound(_peer, 1);
        return in.read();
    }
    
    public int read(byte dest[]) throws IOException {
        int read = in.read(dest);
        _context.bandwidthLimiter().delayInbound(_peer, read);
        return read;
    }
    
    public int read(byte dest[], int off, int len) throws IOException {
        int read = in.read(dest, off, len);
        _context.bandwidthLimiter().delayInbound(_peer, read);
        return read;
    }
    public long skip(long numBytes) throws IOException {
        long skip = in.skip(numBytes);
        _context.bandwidthLimiter().delayInbound(_peer, (int)skip);
        return skip;
    }
}

@@ -645,24 +645,68 @@
 t _context;%0A
+    private boolean _pullFromOutbound;%0A    %0A
     public B
@@ -798,16 +798,391 @@
 peer) %7B%0A
+        this(context, source, peer, false);%0A    %7D%0A    /**%0A     * @param pullFromOutbound even though this is an input stream, if this is true, use the%0A     *                         context's outbound bandwidth limiter queue for delays%0A     */%0A    public BandwidthLimitedInputStream(RouterContext context, InputStream source, RouterIdentity peer, boolean pullFromOutbound) %7B%0A
         
@@ -1242,24 +1242,70 @@
 eer = peer;%0A
+        _pullFromOutbound = pullFromOutbound;%0A
     %7D%0A    %0A 
@@ -1338,32 +1338,145 @@
 s IOException %7B%0A
+        if (_pullFromOutbound)%0A            _context.bandwidthLimiter().delayOutbound(_peer, 1);%0A        else%0A    
         _context
@@ -1644,16 +1644,132 @@
 (dest);%0A
+        if (_pullFromOutbound)%0A            _context.bandwidthLimiter().delayOutbound(_peer, read);%0A        else%0A    
         
@@ -1971,16 +1971,132 @@
 , len);%0A
+        if (_pullFromOutbound)%0A            _context.bandwidthLimiter().delayOutbound(_peer, read);%0A        else%0A    
         
@@ -2273,16 +2273,137 @@
 Bytes);%0A
+        if (_pullFromOutbound)%0A            _context.bandwidthLimiter().delayOutbound(_peer, (int)skip);%0A        else%0A    
         

allow the stream to optionally pull from the output stream's bandwidth limit queue (useful in very strange situations)