franta-hg@107: /* franta-hg@107: GNU-Classpath Extensions: javamail franta-hg@107: Copyright (C) 2002 Chris Burdess franta-hg@107: franta-hg@107: For more information on the classpathx please mail: franta-hg@107: nferrier@tapsellferrier.co.uk franta-hg@107: franta-hg@107: This program is free software; you can redistribute it and/or franta-hg@107: modify it under the terms of the GNU Lesser General Public License franta-hg@107: as published by the Free Software Foundation; either version 2 franta-hg@107: of the License, or (at your option) any later version. franta-hg@107: franta-hg@107: This program is distributed in the hope that it will be useful, franta-hg@107: but WITHOUT ANY WARRANTY; without even the implied warranty of franta-hg@107: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the franta-hg@107: GNU General Public License for more details. franta-hg@107: franta-hg@107: You should have received a copy of the GNU General Public License franta-hg@107: along with this program; if not, write to the Free Software franta-hg@107: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. franta-hg@107: */ franta-hg@107: package org.sonews.util.io; // original package: gnu.mail.providers.smtp franta-hg@107: franta-hg@107: import java.io.FilterOutputStream; franta-hg@107: import java.io.IOException; franta-hg@107: franta-hg@107: /** franta-hg@107: * An output stream implementing the SMTP specification for dot escaping. franta-hg@107: * Objects of this class are intended to be chained with CRLFOutputStream franta-hg@107: * instances as all SMTP output is intended to be CRLF-escaped. franta-hg@107: * franta-hg@107: * @author dog@gnu.org franta-hg@107: * @version 0.1 franta-hg@107: */ franta-hg@107: public class SMTPOutputStream extends FilterOutputStream { franta-hg@107: franta-hg@107: /** franta-hg@107: * The LF octet. franta-hg@107: */ franta-hg@107: public static final int LF = 0x0a; franta-hg@107: /** franta-hg@107: * The dot octet. franta-hg@107: */ franta-hg@107: public static final int DOT = 0x2e; franta-hg@107: /** franta-hg@107: * The last octet read. franta-hg@107: */ franta-hg@107: protected int last; franta-hg@107: franta-hg@107: /** franta-hg@107: * Constructs an SMTP output stream connected to the specified output stream. franta-hg@107: * The underlying output stream should coordinate proper CRLF pairs at franta-hg@107: * line ends. franta-hg@107: * @param out a CRLFOutputStream franta-hg@107: */ franta-hg@107: public SMTPOutputStream(CRLFOutputStream out) { franta-hg@107: super(out); franta-hg@107: } franta-hg@107: franta-hg@107: /** franta-hg@107: * Writes a character to the underlying stream. franta-hg@107: * @exception IOException if an I/O error occurred franta-hg@107: */ franta-hg@107: @Override franta-hg@107: public void write(int ch) throws IOException { franta-hg@107: if (ch == DOT) { franta-hg@107: if (last == LF) { franta-hg@107: out.write(DOT); franta-hg@107: } franta-hg@107: } franta-hg@107: out.write(ch); franta-hg@107: last = ch; franta-hg@107: } franta-hg@107: franta-hg@107: /** franta-hg@107: * Writes a byte array to the underlying stream. franta-hg@107: * @exception IOException if an I/O error occurred franta-hg@107: */ franta-hg@107: @Override franta-hg@107: public void write(byte b[]) throws IOException { franta-hg@107: write(b, 0, b.length); franta-hg@107: } franta-hg@107: franta-hg@107: /** franta-hg@107: * Writes a portion of a byte array to the underlying stream. franta-hg@107: * @exception IOException if an I/O error occurred franta-hg@107: */ franta-hg@107: @Override franta-hg@107: public void write(byte b[], int off, int len) throws IOException { franta-hg@107: int d = off; franta-hg@107: len += off; franta-hg@107: for (int i = off; i < len; i++) { franta-hg@107: switch (b[i]) { franta-hg@107: case DOT: franta-hg@107: int l = (i - d); franta-hg@107: if (l > 0) { franta-hg@107: out.write(b, d, l); franta-hg@107: } franta-hg@107: d = i; franta-hg@107: if (last == LF) { franta-hg@107: out.write(DOT); franta-hg@107: } franta-hg@107: break; franta-hg@107: } franta-hg@107: last = b[i]; franta-hg@107: } franta-hg@107: if (len - d > 0) { franta-hg@107: out.write(b, d, len - d); franta-hg@107: } franta-hg@107: } franta-hg@107: }