blob: 621a0d92abd83dba3ff7f00555e953a8076e8f79 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package sun.misc;
26
27import java.io.InputStream;
28import java.io.OutputStream;
29import java.io.PrintStream;
30import java.io.IOException;
31
32/**
33 * This class implements a Berkeley uu character encoder. This encoder
34 * was made famous by uuencode program.
35 *
36 * The basic character coding is algorithmic, taking 6 bits of binary
37 * data and adding it to an ASCII ' ' (space) character. This converts
38 * these six bits into a printable representation. Note that it depends
39 * on the ASCII character encoding standard for english. Groups of three
40 * bytes are converted into 4 characters by treating the three bytes
41 * a four 6 bit groups, group 1 is byte 1's most significant six bits,
42 * group 2 is byte 1's least significant two bits plus byte 2's four
43 * most significant bits. etc.
44 *
45 * In this encoding, the buffer prefix is:
46 * <pre>
47 * begin [mode] [filename]
48 * </pre>
49 *
50 * This is followed by one or more lines of the form:
51 * <pre>
52 * (len)(data)(data)(data) ...
53 * </pre>
54 * where (len) is the number of bytes on this line. Note that groupings
55 * are always four characters, even if length is not a multiple of three
56 * bytes. When less than three characters are encoded, the values of the
57 * last remaining bytes is undefined and should be ignored.
58 *
59 * The last line of data in a uuencoded file is represented by a single
60 * space character. This is translated by the decoding engine to a line
61 * length of zero. This is immediately followed by a line which contains
62 * the word 'end[newline]'
63 *
64 * @author Chuck McManis
65 * @see CharacterEncoder
66 * @see UUDecoder
67 */
68public class UUEncoder extends CharacterEncoder {
69
70 /**
71 * This name is stored in the begin line.
72 */
73 private String bufferName;
74
75 /**
76 * Represents UNIX(tm) mode bits. Generally three octal digits representing
77 * read, write, and execute permission of the owner, group owner, and
78 * others. They should be interpreted as the bit groups:
79 * (owner) (group) (others)
80 * rwx rwx rwx (r = read, w = write, x = execute)
81 *
82 * By default these are set to 644 (UNIX rw-r--r-- permissions).
83 */
84 private int mode;
85
86
87 /**
88 * Default - buffer begin line will be:
89 * <pre>
90 * begin 644 encoder.buf
91 * </pre>
92 */
93 public UUEncoder() {
94 bufferName = "encoder.buf";
95 mode = 644;
96 }
97
98 /**
99 * Specifies a name for the encoded buffer, begin line will be:
100 * <pre>
101 * begin 644 [FNAME]
102 * </pre>
103 */
104 public UUEncoder(String fname) {
105 bufferName = fname;
106 mode = 644;
107 }
108
109 /**
110 * Specifies a name and mode for the encoded buffer, begin line will be:
111 * <pre>
112 * begin [MODE] [FNAME]
113 * </pre>
114 */
115 public UUEncoder(String fname, int newMode) {
116 bufferName = fname;
117 mode = newMode;
118 }
119
120 /** number of bytes per atom in uuencoding is 3 */
121 protected int bytesPerAtom() {
122 return (3);
123 }
124
125 /** number of bytes per line in uuencoding is 45 */
126 protected int bytesPerLine() {
127 return (45);
128 }
129
130 /**
131 * encodeAtom - take three bytes and encodes them into 4 characters
132 * If len is less than 3 then remaining bytes are filled with '1'.
133 * This insures that the last line won't end in spaces and potentiallly
134 * be truncated.
135 */
136 protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len)
137 throws IOException {
138 byte a, b = 1, c = 1;
139 int c1, c2, c3, c4;
140
141 a = data[offset];
142 if (len > 1) {
143 b = data[offset+1];
144 }
145 if (len > 2) {
146 c = data[offset+2];
147 }
148
149 c1 = (a >>> 2) & 0x3f;
150 c2 = ((a << 4) & 0x30) | ((b >>> 4) & 0xf);
151 c3 = ((b << 2) & 0x3c) | ((c >>> 6) & 0x3);
152 c4 = c & 0x3f;
153 outStream.write(c1 + ' ');
154 outStream.write(c2 + ' ');
155 outStream.write(c3 + ' ');
156 outStream.write(c4 + ' ');
157 return;
158 }
159
160 /**
161 * Encode the line prefix which consists of the single character. The
162 * lenght is added to the value of ' ' (32 decimal) and printed.
163 */
164 protected void encodeLinePrefix(OutputStream outStream, int length)
165 throws IOException {
166 outStream.write((length & 0x3f) + ' ');
167 }
168
169
170 /**
171 * The line suffix for uuencoded files is simply a new line.
172 */
173 protected void encodeLineSuffix(OutputStream outStream) throws IOException {
174 pStream.println();
175 }
176
177 /**
178 * encodeBufferPrefix writes the begin line to the output stream.
179 */
180 protected void encodeBufferPrefix(OutputStream a) throws IOException {
181 super.pStream = new PrintStream(a);
182 super.pStream.print("begin "+mode+" ");
183 if (bufferName != null) {
184 super.pStream.println(bufferName);
185 } else {
186 super.pStream.println("encoder.bin");
187 }
188 super.pStream.flush();
189 }
190
191 /**
192 * encodeBufferSuffix writes the single line containing space (' ') and
193 * the line containing the word 'end' to the output stream.
194 */
195 protected void encodeBufferSuffix(OutputStream a) throws IOException {
196 super.pStream.println(" \nend");
197 super.pStream.flush();
198 }
199
200}