001: /*
002: * MimeOutputStream.java - A Filter stream for MIME encoding
003: *
004: * Copyright (C) 2000,,2003 2002 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or (at your option) any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: package net.sourceforge.groboutils.util.io.v1;
024:
025: import java.io.FilterOutputStream;
026: import java.io.OutputStream;
027: import java.io.IOException;
028: import java.awt.TextComponent;
029:
030: /**
031: * java.io.FilterOutputStream implementation for Mime base 64. Not incredibly
032: * efficient, but it works and is small.
033: * <P>
034: * All we need to implement are:
035: * <ul>
036: * <li>write(int)</li>
037: * <li>flush()</li>
038: * </ul>
039: *
040: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
041: * @since 0.9.0 Alpha (early 2000)
042: * @version $Date: 2003/02/10 22:52:45 $
043: */
044: public class MimeOutputStream extends FilterOutputStream {
045: private int bits = 0, spare = 0;
046:
047: /**
048: * Mime character set translation
049: */
050: private static final int[] charset = { 'A', 'B', 'C', 'D', 'E',
051: 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
052: 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
053: 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
054: 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
055: '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
056: private static final int pad = '=';
057:
058: /** Constructor! */
059: public MimeOutputStream(OutputStream o) {
060: super (o);
061: }
062:
063: /**
064: * Write the specified <code>byte</code>, performing mime encoding.
065: *
066: * <p>Override this method, since all other write methods call it.
067: *
068: * @exception IOException If an I/O error occurs
069: */
070: public void write(int c) throws IOException {
071: int s, t;
072: switch (bits) {
073: case 0:
074: bits++;
075: s = (c >> 2) & 0x3f;
076: spare = c & 0x03;
077: out.write(charset[s]);
078: break;
079: case 1:
080: bits++;
081: s = (spare << 4) | ((c >> 4) & 0x0f);
082: spare = c & 0x0f;
083: out.write(charset[s]);
084: break;
085: case 2:
086: bits = 0;
087: s = (spare << 2) | ((c >> 6) & 0x03);
088: t = c & 0x3f;
089: out.write(charset[s]);
090: out.write(charset[t]);
091: break;
092: }
093: }
094:
095: /**
096: * Flush the stream. If the stream has saved any characters from the
097: * various write() methods in a buffer, write them immediately to their
098: * intended destination. Then, if that destination is another character or
099: * byte stream, flush it. Thus one flush() invocation will flush all the
100: * buffers in a chain of Writers and OutputStreams.
101: * <P>
102: * This version does not buffer, but Mime encoding may have some trailing
103: * stuff, which needs padding.
104: *
105: * @exception IOException If an I/O error occurs
106: */
107: public void flush() throws IOException {
108: switch (bits) {
109: case 1:
110: out.write(charset[spare << 4]);
111: out.write(pad);
112: out.write(pad);
113: break;
114: case 2:
115: out.write(charset[spare << 2]);
116: out.write(pad);
117: break;
118: }
119: super.flush();
120: }
121: }
|