SMTP: dot escaping – imported GNU code.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/org/sonews/util/io/CRLFOutputStream.java Tue Oct 25 10:16:13 2011 +0200
1.3 @@ -0,0 +1,155 @@
1.4 +/* CRLFOutputStream.java --
1.5 +Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
1.6 +
1.7 +This file is part of GNU Classpath.
1.8 +
1.9 +GNU Classpath is free software; you can redistribute it and/or modify
1.10 +it under the terms of the GNU General Public License as published by
1.11 +the Free Software Foundation; either version 2, or (at your option)
1.12 +any later version.
1.13 +
1.14 +GNU Classpath is distributed in the hope that it will be useful, but
1.15 +WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.17 +General Public License for more details.
1.18 +
1.19 +You should have received a copy of the GNU General Public License
1.20 +along with GNU Classpath; see the file COPYING. If not, write to the
1.21 +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1.22 +02110-1301 USA.
1.23 +
1.24 +Linking this library statically or dynamically with other modules is
1.25 +making a combined work based on this library. Thus, the terms and
1.26 +conditions of the GNU General Public License cover the whole
1.27 +combination.
1.28 +
1.29 +As a special exception, the copyright holders of this library give you
1.30 +permission to link this library with independent modules to produce an
1.31 +executable, regardless of the license terms of these independent
1.32 +modules, and to copy and distribute the resulting executable under
1.33 +terms of your choice, provided that you also meet, for each linked
1.34 +independent module, the terms and conditions of the license of that
1.35 +module. An independent module is a module which is not derived from
1.36 +or based on this library. If you modify this library, you may extend
1.37 +this exception to your version of the library, but you are not
1.38 +obligated to do so. If you do not wish to do so, delete this
1.39 +exception statement from your version.
1.40 + */
1.41 +package org.sonews.util.io; // original package: gnu.java.net
1.42 +
1.43 +import java.io.FilterOutputStream;
1.44 +import java.io.IOException;
1.45 +import java.io.OutputStream;
1.46 +import java.io.UnsupportedEncodingException;
1.47 +
1.48 +/**
1.49 + * An output stream that filters LFs into CR/LF pairs.
1.50 + *
1.51 + * @author Chris Burdess (dog@gnu.org)
1.52 + */
1.53 +public class CRLFOutputStream extends FilterOutputStream {
1.54 +
1.55 + static final String US_ASCII = "US-ASCII";
1.56 + /**
1.57 + * The CR octet.
1.58 + */
1.59 + public static final int CR = 13;
1.60 + /**
1.61 + * The LF octet.
1.62 + */
1.63 + public static final int LF = 10;
1.64 + /**
1.65 + * The CR/LF pair.
1.66 + */
1.67 + public static final byte[] CRLF = {CR, LF};
1.68 + /**
1.69 + * The last byte read.
1.70 + */
1.71 + protected int last;
1.72 +
1.73 + /**
1.74 + * Constructs a CR/LF output stream connected to the specified output stream.
1.75 + */
1.76 + public CRLFOutputStream(OutputStream out) {
1.77 + super(out);
1.78 + last = -1;
1.79 + }
1.80 +
1.81 + /**
1.82 + * Writes a character to the underlying stream.
1.83 + * @exception IOException if an I/O error occurred
1.84 + */
1.85 + @Override
1.86 + public void write(int ch) throws IOException {
1.87 + if (ch == CR) {
1.88 + out.write(CRLF);
1.89 + } else if (ch == LF) {
1.90 + if (last != CR) {
1.91 + out.write(CRLF);
1.92 + }
1.93 + } else {
1.94 + out.write(ch);
1.95 + }
1.96 + last = ch;
1.97 + }
1.98 +
1.99 + /**
1.100 + * Writes a byte array to the underlying stream.
1.101 + * @exception IOException if an I/O error occurred
1.102 + */
1.103 + @Override
1.104 + public void write(byte[] b) throws IOException {
1.105 + write(b, 0, b.length);
1.106 + }
1.107 +
1.108 + /**
1.109 + * Writes a portion of a byte array to the underlying stream.
1.110 + * @exception IOException if an I/O error occurred
1.111 + */
1.112 + @Override
1.113 + public void write(byte[] b, int off, int len) throws IOException {
1.114 + int d = off;
1.115 + len += off;
1.116 + for (int i = off; i < len; i++) {
1.117 + switch (b[i]) {
1.118 + case CR:
1.119 + out.write(b, d, i - d);
1.120 + out.write(CRLF, 0, 2);
1.121 + d = i + 1;
1.122 + break;
1.123 + case LF:
1.124 + if (last != CR) {
1.125 + out.write(b, d, i - d);
1.126 + out.write(CRLF, 0, 2);
1.127 + }
1.128 + d = i + 1;
1.129 + break;
1.130 + }
1.131 + last = b[i];
1.132 + }
1.133 + if (len - d > 0) {
1.134 + out.write(b, d, len - d);
1.135 + }
1.136 + }
1.137 +
1.138 + /**
1.139 + * Writes the specified ASCII string to the underlying stream.
1.140 + * @exception IOException if an I/O error occurred
1.141 + */
1.142 + public void write(String text) throws IOException {
1.143 + try {
1.144 + byte[] bytes = text.getBytes(US_ASCII);
1.145 + write(bytes, 0, bytes.length);
1.146 + } catch (UnsupportedEncodingException e) {
1.147 + throw new IOException("The US-ASCII encoding is not supported on this system", e);
1.148 + }
1.149 + }
1.150 +
1.151 + /**
1.152 + * Writes a newline to the underlying stream.
1.153 + * @exception IOException if an I/O error occurred
1.154 + */
1.155 + public void writeln() throws IOException {
1.156 + out.write(CRLF, 0, 2);
1.157 + }
1.158 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/src/org/sonews/util/io/SMTPOutputStream.java Tue Oct 25 10:16:13 2011 +0200
2.3 @@ -0,0 +1,111 @@
2.4 +/*
2.5 +GNU-Classpath Extensions: javamail
2.6 +Copyright (C) 2002 Chris Burdess
2.7 +
2.8 +For more information on the classpathx please mail:
2.9 +nferrier@tapsellferrier.co.uk
2.10 +
2.11 +This program is free software; you can redistribute it and/or
2.12 +modify it under the terms of the GNU Lesser General Public License
2.13 +as published by the Free Software Foundation; either version 2
2.14 +of the License, or (at your option) any later version.
2.15 +
2.16 +This program is distributed in the hope that it will be useful,
2.17 +but WITHOUT ANY WARRANTY; without even the implied warranty of
2.18 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.19 +GNU General Public License for more details.
2.20 +
2.21 +You should have received a copy of the GNU General Public License
2.22 +along with this program; if not, write to the Free Software
2.23 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2.24 + */
2.25 +package org.sonews.util.io; // original package: gnu.mail.providers.smtp
2.26 +
2.27 +import java.io.FilterOutputStream;
2.28 +import java.io.IOException;
2.29 +
2.30 +/**
2.31 + * An output stream implementing the SMTP specification for dot escaping.
2.32 + * Objects of this class are intended to be chained with CRLFOutputStream
2.33 + * instances as all SMTP output is intended to be CRLF-escaped.
2.34 + *
2.35 + * @author dog@gnu.org
2.36 + * @version 0.1
2.37 + */
2.38 +public class SMTPOutputStream extends FilterOutputStream {
2.39 +
2.40 + /**
2.41 + * The LF octet.
2.42 + */
2.43 + public static final int LF = 0x0a;
2.44 + /**
2.45 + * The dot octet.
2.46 + */
2.47 + public static final int DOT = 0x2e;
2.48 + /**
2.49 + * The last octet read.
2.50 + */
2.51 + protected int last;
2.52 +
2.53 + /**
2.54 + * Constructs an SMTP output stream connected to the specified output stream.
2.55 + * The underlying output stream should coordinate proper CRLF pairs at
2.56 + * line ends.
2.57 + * @param out a CRLFOutputStream
2.58 + */
2.59 + public SMTPOutputStream(CRLFOutputStream out) {
2.60 + super(out);
2.61 + }
2.62 +
2.63 + /**
2.64 + * Writes a character to the underlying stream.
2.65 + * @exception IOException if an I/O error occurred
2.66 + */
2.67 + @Override
2.68 + public void write(int ch) throws IOException {
2.69 + if (ch == DOT) {
2.70 + if (last == LF) {
2.71 + out.write(DOT);
2.72 + }
2.73 + }
2.74 + out.write(ch);
2.75 + last = ch;
2.76 + }
2.77 +
2.78 + /**
2.79 + * Writes a byte array to the underlying stream.
2.80 + * @exception IOException if an I/O error occurred
2.81 + */
2.82 + @Override
2.83 + public void write(byte b[]) throws IOException {
2.84 + write(b, 0, b.length);
2.85 + }
2.86 +
2.87 + /**
2.88 + * Writes a portion of a byte array to the underlying stream.
2.89 + * @exception IOException if an I/O error occurred
2.90 + */
2.91 + @Override
2.92 + public void write(byte b[], int off, int len) throws IOException {
2.93 + int d = off;
2.94 + len += off;
2.95 + for (int i = off; i < len; i++) {
2.96 + switch (b[i]) {
2.97 + case DOT:
2.98 + int l = (i - d);
2.99 + if (l > 0) {
2.100 + out.write(b, d, l);
2.101 + }
2.102 + d = i;
2.103 + if (last == LF) {
2.104 + out.write(DOT);
2.105 + }
2.106 + break;
2.107 + }
2.108 + last = b[i];
2.109 + }
2.110 + if (len - d > 0) {
2.111 + out.write(b, d, len - d);
2.112 + }
2.113 + }
2.114 +}