2 * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved.
4 * The Sun Project JXTA(TM) Software License
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * 3. The end-user documentation included with the redistribution, if any, must
17 * include the following acknowledgment: "This product includes software
18 * developed by Sun Microsystems, Inc. for JXTA(TM) technology."
19 * Alternately, this acknowledgment may appear in the software itself, if
20 * and wherever such third-party acknowledgments normally appear.
22 * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must
23 * not be used to endorse or promote products derived from this software
24 * without prior written permission. For written permission, please contact
25 * Project JXTA at http://www.jxta.org.
27 * 5. Products derived from this software may not be called "JXTA", nor may
28 * "JXTA" appear in their name, without prior written permission of Sun.
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
32 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN
33 * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
36 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
39 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 * JXTA is a registered trademark of Sun Microsystems, Inc. in the United
42 * States and other countries.
44 * Please see the license information page at :
45 * <http://www.jxta.org/project/www/license.html> for instructions on use of
46 * the license in source files.
48 * ====================================================================
50 * This software consists of voluntary contributions made by many individuals
51 * on behalf of Project JXTA. For more information on Project JXTA, please see
52 * http://www.jxta.org.
54 * This license is based on the BSD license adopted by the Apache Foundation.
57 package net.jxta.impl.util;
60 import java.io.OutputStream;
61 import java.io.Writer;
63 import java.io.IOException;
64 import java.io.StringReader;
65 import java.io.ByteArrayOutputStream;
66 import java.io.StringWriter;
70 * An OutputStream implementation which encodes the written bytes into BASE64
71 * encoded character data and writes the output to an associated text Writer.
73 * <p/>This implementation is not thread safe.
75 * @see net.jxta.impl.util.BASE64InputStream
76 * @see <a href="http://www.ietf.org/rfc/rfc2045.txt" target="_blank">IETF RFC 2045 <i>MIME : Format of Internet Message Bodies</i></a>
78 public class BASE64OutputStream extends OutputStream {
81 * If <code>true</code> then the output stream has been closed.
83 private boolean closed = false;
88 private Writer sendTo = null;
91 * Column width to breakup out.
93 private final int columnWidth;
96 * Current output column.
98 private int column = 0;
101 * Buffer for incomplete characters.
103 private byte[] buffer = new byte[] { 0, 0, 0 };
106 * The number of characters currently in the buffer.
108 private byte inBuffer = 0;
111 * Construct a BASE64 Output Stream.
113 * @param sendTo The text Writer to which the BASE64 output will be
116 public BASE64OutputStream(Writer sendTo) {
121 * Construct a BASE64 Output Stream. The output will be broken into lines
122 * <code>columnWidth</code> long.
124 * @param sendTo The text Writer to which the BASE64 output will be
126 * @param columnWidth The width of lines to break output into.
128 public BASE64OutputStream(Writer sendTo, int columnWidth) {
129 this.sendTo = sendTo;
130 this.columnWidth = columnWidth;
137 public void write(int b) throws IOException {
139 throw new IOException("OutputStream closed.");
142 buffer[ inBuffer++ ] = (byte) b;
144 if (buffer.length == inBuffer) {
152 * <p/>The output writer is <b>NOT</b> closed.
155 public void close() throws IOException {
166 public void flush() throws IOException {
171 * Write a full or partial buffer to the output writer.
173 private void writeBuffer() throws IOException {
178 int val = ((buffer[0] & 0x00FF) << 16) + ((buffer[1] & 0x00FF) << 8) + (buffer[2] & 0x00FF);
180 int c0 = (val >> 18) & 0x003F;
181 int c1 = (val >> 12) & 0x003F;
182 int c2 = (val >> 6) & 0x003F;
183 int c3 = val & 0x003F;
185 if ((columnWidth > 0) && (column > columnWidth)) {
190 sendTo.write(encodeSixBits(c0));
191 sendTo.write(encodeSixBits(c1));
194 sendTo.write(encodeSixBits(c2));
200 sendTo.write(encodeSixBits(c3));
214 * BASE64 Encoding Table
216 static final char encode[] = {
217 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X'
219 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v'
221 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
225 * Encode six bits into a character using the standard BASE64 table.
227 * @param b the bits to encode. b must be >=0 and <= 63
228 * @return the appropriate character for the input value.
230 private static char encodeSixBits(int b) {
233 if ((b < 0) || (b > 63)) {
234 throw new IllegalArgumentException("bad encode value");