Source code: Freenet/Conduit.java
1 package Freenet;
2 import Freenet.support.*;
3 import java.io.*;
4 /*
5 This code is part of the Java Adaptive Network Client by Ian Clarke.
6 It is distributed under the GNU Public Licence (GPL) version 2. See
7 http://www.gnu.org/ for further details of the GPL.
8
9 Explanation of Code Versions:
10 0.0.0 = Initial Description
11 0.0.1 = API Specified
12 0.x (x>0) = Partial Implementation
13 x.0 (x>0) = Operational
14
15 Requires Classes: java.io.* (JDK 1.1)
16 Callback (1.0)
17
18 */
19
20 /**
21 * This class creates a conduit between an InputStream and an
22 * OutputStream and when the feed method of this object is called
23 * the InputStream will be fed into the output stream of this
24 * object.
25 *
26 * @version 1.0
27 * @author <A HREF="mailto:I.Clarke@strs.co.uk">Ian Clarke</A>
28 **/
29
30 public class Conduit extends Thread
31 {
32 private InputStream in;
33 private OutputStream out;
34 private Callback cb;
35 private Callback icb;
36 private ByteCounter counter;
37 private long bytesToMove = -1;
38 private long bytesMoved = 0;
39 public long bytesMoved() {return bytesMoved;}
40
41 /**
42 * @param i The stream to read data from
43 * @param o The stream to send data to
44 **/
45 public Conduit(InputStream i, OutputStream o)
46 {
47 this(i,o,null);
48 }
49 /**
50 * @param i The stream to read data from
51 * @param o The stream to send data to
52 * @param counter The counter to count the bytes
53 **/
54 public Conduit(InputStream i, OutputStream o, ByteCounter counter) {
55 this.in = i;
56 this.out = o;
57 this.counter = counter;
58 }
59
60
61
62 /**
63 * Commences the transfer from Input to Output Streams asynchronously
64 * @param cb An object implementing the Callback interface which will be
65 * called when the stream finnishes.
66 **/
67 public void asyncFeed(Callback cb)
68 {
69 if (!isAlive()) {
70 this.cb=cb;
71 this.start();
72 }
73 }
74
75 /**
76 * Commences the transfer from Input to Output Stream asynchronously
77 * until a number of bytes have been transfered
78 * @param cb An object implementing the Callback interface which will be
79 * called when the stream finnishes.
80 * @param icb An object of implementing the Callback interface which will
81 * called if the stream is interupted before reading all the
82 * of bytes has finnished.
83 * @param n the number of bytes to read
84 **/
85 public void asyncFeed(Callback cb, Callback icb, long n)
86 {
87 if (!isAlive()) {
88 this.cb=cb;
89 this.icb = icb;
90 this.bytesToMove = n;
91 this.start();
92 }
93 }
94
95 /**
96 * Transfer from Input to Output Streams, doesn't return until transfer
97 * complete
98 * @depreciated Use asyncFeed() and wait() on one of the streams instead (this may even lock now)
99 **/
100 public void syncFeed()
101 {
102 if (!isAlive()) this.run();
103 }
104
105 public void run()
106 {
107 byte[] buffer = new byte[512];
108 int bytes_read;
109 Logger.log("Conduit.java","Conduit starting",Logger.DEBUG);
110 synchronized(in) {
111 synchronized(out) {
112 try {
113 for(;;) {
114 bytes_read = in.read(buffer, 0, bytesToMove < 0 ||
115 (bytesToMove - bytesMoved >= buffer.length)
116 ? buffer.length
117 : (int) (bytesToMove - bytesMoved));
118
119 if (bytes_read > 0)
120 out.write(buffer, 0, bytes_read);
121 bytesMoved = bytesMoved + bytes_read;
122
123
124 if (counter != null)
125 counter.count(bytes_read == -1 ? 0 : bytes_read);
126
127 if (bytes_read == -1 || bytesMoved == bytesToMove) {
128 if (bytesToMove >= 0 && bytesMoved != bytesToMove && icb != null)
129 icb.callback();
130 else if (cb != null)
131 cb.callback();
132
133 if (counter != null)
134 counter.finished();
135 return;
136 }
137
138 }
139 }
140 catch (IOException e) {
141 Logger.log("Conduit.java",e.toString(),Logger.ERROR);
142 if (icb != null)
143 icb.callback();
144 else if (cb != null)
145 cb.callback();
146 } finally {
147 Logger.log("Conduit.java","Conduit finished",Logger.DEBUG);
148 // notify the streams
149 // out.notifyAll();
150
151 in.notifyAll();
152 }
153 }
154 }
155 }
156 }
157