KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > mail > util > UUEncoderStream


1 /*
2   GNU-Classpath Extensions: javamail
3   Copyright (C) 2000 Andrew Selkirk
4
5   For more information on the classpathx please mail: nferrier@tapsellferrier.co.uk
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public License
9   as published by the Free Software Foundation; either version 2
10   of the License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */

21 package gnu.mail.util;
22
23
24 // Imports
25
import java.io.OutputStream JavaDoc;
26 import java.io.FilterOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28
29 /** a stream that performs UU Encoding.
30  *
31  * @author Andrew Selkirk
32  * @version 1.0
33  * @see java.io.FilterOutputStream
34  **/

35 public class UUEncoderStream
36 extends FilterOutputStream JavaDoc
37 {
38
39   /**
40    * Encoding buffer. Up to 45 bytes are read in before encoding
41    * is started (unless a flush is initiated).
42    */

43   private byte[] buffer;
44
45   /**
46    * Current number of bytes in buffer.
47    */

48   private int bufsize;
49
50   /**
51    * Flag to indicate if prefix written.
52    */

53   private boolean wrotePrefix;
54
55   /**
56    * Name of file to be uuencoded.
57    */

58   protected String JavaDoc name;
59
60   /**
61    * Permission mode of file.
62    */

63   protected int mode;
64
65   /**
66    * Create a new UU-Encoding stream with the default name
67    * "encoder.buf" with the permission mode 644.
68    * @param stream Output stream
69    */

70   public UUEncoderStream(OutputStream JavaDoc stream)
71   {
72     this(stream, "encoder.buf", 644);
73   } // UUEncoderStream()
74

75   /**
76    * Create a new UU-Encoding stream with the default name
77    * permission mode 644.
78    * @param stream Output stream
79    * @param name File name
80    */

81   public UUEncoderStream(OutputStream JavaDoc stream, String JavaDoc name)
82   {
83     this(stream, name, 644);
84   } // UUEncoderStream()
85

86   /**
87    * Create a new UU-Encoding stream.
88    * @param stream Output stream
89    * @param name File name
90    * @param mode File permission mode
91    */

92   public UUEncoderStream(OutputStream JavaDoc stream, String JavaDoc name, int mode)
93   {
94     super(stream);
95     this.name = name;
96     this.mode = mode;
97     wrotePrefix = false;
98     buffer = new byte[45];
99     bufsize = 0;
100   } // UUEncoderStream()
101

102
103   //-------------------------------------------------------------
104
// Methods ----------------------------------------------------
105
//-------------------------------------------------------------
106

107   /**
108    * Flush encoding buffer.
109    * @exception IOException IO Exception occurred
110    */

111   public void flush() throws IOException JavaDoc
112   {
113     encode();
114   } // flush()
115

116   /**
117    * Write bytes to encoding stream.
118    * @param bytes Byte array to read values from
119    * @param offset Offset to start reading bytes from
120    * @param length Number of bytes to read
121    * @exception IOException IO Exception occurred
122    */

123   public void write(byte[] bytes, int offset, int length)
124   throws IOException JavaDoc
125   {
126
127     // Note: This implementation is not as efficient as
128
// it could be. Instead of delegating the work to
129
// write(int), the bytes should be written in bulk
130
// to the buffer and initiating encoding if necessary.
131
// This idea does introduce some duplication of code.
132

133     // Variables
134
int index;
135
136     // Write Bytes
137
for (index = offset; index < length; index++)
138     {
139       write(bytes[index]);
140     } // for: index
141

142   } // write()
143

144   /**
145    * Write bytes to stream.
146    * @param bytes Byte array to write to stream
147    * @exception IOException IO Exception occurred
148    */

149   public void write(byte[] bytes) throws IOException JavaDoc
150   {
151     write(bytes, 0, bytes.length);
152   } // write()
153

154   /**
155    * Write a byte to the stream.
156    * @param b Byte to write to the stream
157    * @exception IOException IO Exception occurred
158    */

159   public void write(int b) throws IOException JavaDoc
160   {
161
162     // Check for Written Prefix
163
if (wrotePrefix == false)
164     {
165       writePrefix();
166     } // if
167

168     // Add Byte to Buffer
169
buffer[bufsize] = (byte) b;
170     bufsize += 1;
171
172     // Check for Flush
173
if (bufsize == buffer.length)
174     {
175       encode();
176     } // if
177

178   } // write()
179

180   /**
181    * Close stream.
182    * @exception IOException IO Exception occurred
183    */

184   public void close() throws IOException JavaDoc
185   {
186
187     // Flush Encoding buffer
188
flush();
189
190     // Write Encoding Suffix
191
writeSuffix();
192
193     // Close
194
out.close();
195
196   } // close()
197

198   /**
199    * Flush encoding buffer.
200    * @exception IOException IO Exception occurred
201    */

202   private void encode() throws IOException JavaDoc
203   {
204
205     // Variables
206
int index;
207     int c1;
208     int c2;
209     int c3;
210     int c4;
211     int a;
212     int b;
213     int c;
214
215     // Write Line prefix
216
super.write((bufsize & 0x3f) + ' ');
217
218     // Process bytes in groups of three
219
index = 0;
220     while (index < bufsize)
221     {
222
223       // Get Bytes
224
a = buffer[index];
225       if (index + 1 < bufsize)
226       {
227     b = buffer[index+1];
228       } else
229       {
230     b = 1;
231       } // if
232
if (index + 2 < bufsize)
233       {
234     c = buffer[index+2];
235       } else
236       {
237     c = 1;
238       } // if
239

240       // Calculate UU Encoding
241
c1 = (a >>> 2) & 0xff;
242       c2 = ((a << 4) & 0x30) | ((b >>> 4) & 0xf);
243       c3 = ((b << 2) & 0x3c) | ((c >>> 6) & 0x3);
244       c4 = c & 0x3f;
245
246       // Write Encoded Characters
247
out.write(c1 + ' ');
248       out.write(c2 + ' ');
249       out.write(c3 + ' ');
250       out.write(c4 + ' ');
251
252       // Increment position
253
index += 3;
254
255     } // while
256

257     // Write Newline
258
out.write('\n');
259
260     // Reset Buffer size
261
bufsize = 0;
262
263   } // encode()
264

265   /**
266    * Set the name and mode for this uu encoded stream. Note
267    * that this is only valid before data has been uuencoded as
268    * this information is written at the beginning of the stream.
269    * @param name File name
270    * @param mode Permission mode
271    */

272   public void setNameMode(String JavaDoc name, int mode)
273   {
274     this.name = name;
275     this.mode = mode;
276   } // setNameMode()
277

278   /**
279    * Write uuencoding prefix. Constructed as "begin <mode> <name>".
280    * @exception IO Exception has occurred
281    */

282   private void writePrefix() throws IOException JavaDoc
283   {
284
285     // Variables
286
StringBuffer JavaDoc prefix;
287     String JavaDoc modeString;
288
289     // Construct Prefix
290
prefix = new StringBuffer JavaDoc();
291     prefix.append("begin ");
292     if (mode < 100)
293     {
294       prefix.append("0");
295     } // if
296
if (mode < 10)
297     {
298       prefix.append("0");
299     } // if
300
prefix.append(mode);
301     prefix.append(" " + name + "\n");
302
303     // Write Prefix to stream
304
out.write(prefix.toString().getBytes());
305
306     // Flag that prefix has been written
307
wrotePrefix = true;
308
309   } // writePrefix()
310

311   /**
312    * Write uuencoding suffix. Constructed as
313    * " <newline>end<newline>".
314    * @exception IO Exception has occurred
315    */

316   private void writeSuffix() throws IOException JavaDoc
317   {
318
319     // Variables
320
String JavaDoc suffix;
321
322     // Construct Suffix
323
suffix = " \nend\n";
324
325     // Write Suffix
326
out.write(suffix.getBytes());
327
328   } // writeSuffix()
329

330
331 } // UUEncoderStream
332
Popular Tags