src/org/sonews/util/io/SMTPOutputStream.java
author František Kučera <franta-hg@frantovo.cz>
Tue Oct 25 10:16:13 2011 +0200 (2011-10-25)
changeset 107 b723308e1359
permissions -rw-r--r--
SMTP: dot escaping – imported GNU code.
franta-hg@107
     1
/*
franta-hg@107
     2
GNU-Classpath Extensions: javamail
franta-hg@107
     3
Copyright (C) 2002 Chris Burdess
franta-hg@107
     4
franta-hg@107
     5
For more information on the classpathx please mail:
franta-hg@107
     6
nferrier@tapsellferrier.co.uk
franta-hg@107
     7
franta-hg@107
     8
This program is free software; you can redistribute it and/or
franta-hg@107
     9
modify it under the terms of the GNU Lesser General Public License
franta-hg@107
    10
as published by the Free Software Foundation; either version 2
franta-hg@107
    11
of the License, or (at your option) any later version.
franta-hg@107
    12
franta-hg@107
    13
This program is distributed in the hope that it will be useful,
franta-hg@107
    14
but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@107
    15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@107
    16
GNU General Public License for more details.
franta-hg@107
    17
franta-hg@107
    18
You should have received a copy of the GNU General Public License
franta-hg@107
    19
along with this program; if not, write to the Free Software
franta-hg@107
    20
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
franta-hg@107
    21
 */
franta-hg@107
    22
package org.sonews.util.io; // original package: gnu.mail.providers.smtp
franta-hg@107
    23
franta-hg@107
    24
import java.io.FilterOutputStream;
franta-hg@107
    25
import java.io.IOException;
franta-hg@107
    26
franta-hg@107
    27
/**
franta-hg@107
    28
 * An output stream implementing the SMTP specification for dot escaping.
franta-hg@107
    29
 * Objects of this class are intended to be chained with CRLFOutputStream
franta-hg@107
    30
 * instances as all SMTP output is intended to be CRLF-escaped.
franta-hg@107
    31
 *
franta-hg@107
    32
 * @author dog@gnu.org
franta-hg@107
    33
 * @version 0.1
franta-hg@107
    34
 */
franta-hg@107
    35
public class SMTPOutputStream extends FilterOutputStream {
franta-hg@107
    36
franta-hg@107
    37
	/**
franta-hg@107
    38
	 * The LF octet.
franta-hg@107
    39
	 */
franta-hg@107
    40
	public static final int LF = 0x0a;
franta-hg@107
    41
	/**
franta-hg@107
    42
	 * The dot octet.
franta-hg@107
    43
	 */
franta-hg@107
    44
	public static final int DOT = 0x2e;
franta-hg@107
    45
	/**
franta-hg@107
    46
	 * The last octet read.
franta-hg@107
    47
	 */
franta-hg@107
    48
	protected int last;
franta-hg@107
    49
franta-hg@107
    50
	/**
franta-hg@107
    51
	 * Constructs an SMTP output stream connected to the specified output stream.
franta-hg@107
    52
	 * The underlying output stream should coordinate proper CRLF pairs at
franta-hg@107
    53
	 * line ends.
franta-hg@107
    54
	 * @param out a CRLFOutputStream
franta-hg@107
    55
	 */
franta-hg@107
    56
	public SMTPOutputStream(CRLFOutputStream out) {
franta-hg@107
    57
		super(out);
franta-hg@107
    58
	}
franta-hg@107
    59
franta-hg@107
    60
	/**
franta-hg@107
    61
	 * Writes a character to the underlying stream.
franta-hg@107
    62
	 * @exception IOException if an I/O error occurred
franta-hg@107
    63
	 */
franta-hg@107
    64
	@Override
franta-hg@107
    65
	public void write(int ch) throws IOException {
franta-hg@107
    66
		if (ch == DOT) {
franta-hg@107
    67
			if (last == LF) {
franta-hg@107
    68
				out.write(DOT);
franta-hg@107
    69
			}
franta-hg@107
    70
		}
franta-hg@107
    71
		out.write(ch);
franta-hg@107
    72
		last = ch;
franta-hg@107
    73
	}
franta-hg@107
    74
franta-hg@107
    75
	/**
franta-hg@107
    76
	 * Writes a byte array to the underlying stream.
franta-hg@107
    77
	 * @exception IOException if an I/O error occurred
franta-hg@107
    78
	 */
franta-hg@107
    79
	@Override
franta-hg@107
    80
	public void write(byte b[]) throws IOException {
franta-hg@107
    81
		write(b, 0, b.length);
franta-hg@107
    82
	}
franta-hg@107
    83
franta-hg@107
    84
	/**
franta-hg@107
    85
	 * Writes a portion of a byte array to the underlying stream.
franta-hg@107
    86
	 * @exception IOException if an I/O error occurred
franta-hg@107
    87
	 */
franta-hg@107
    88
	@Override
franta-hg@107
    89
	public void write(byte b[], int off, int len) throws IOException {
franta-hg@107
    90
		int d = off;
franta-hg@107
    91
		len += off;
franta-hg@107
    92
		for (int i = off; i < len; i++) {
franta-hg@107
    93
			switch (b[i]) {
franta-hg@107
    94
				case DOT:
franta-hg@107
    95
					int l = (i - d);
franta-hg@107
    96
					if (l > 0) {
franta-hg@107
    97
						out.write(b, d, l);
franta-hg@107
    98
					}
franta-hg@107
    99
					d = i;
franta-hg@107
   100
					if (last == LF) {
franta-hg@107
   101
						out.write(DOT);
franta-hg@107
   102
					}
franta-hg@107
   103
					break;
franta-hg@107
   104
			}
franta-hg@107
   105
			last = b[i];
franta-hg@107
   106
		}
franta-hg@107
   107
		if (len - d > 0) {
franta-hg@107
   108
			out.write(b, d, len - d);
franta-hg@107
   109
		}
franta-hg@107
   110
	}
franta-hg@107
   111
}