1 /*
2 * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3 * Copyright (C) 2010 Mickael Guessant
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 package davmail.exchange;
20
21 import java.io.FilterOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24
25 /**
26 * RFC 1939: 3 Basic Operations
27 * [...]
28 * If any line begins with the termination octet, the line is "byte-stuffed" by
29 * pre-pending the termination octet to that line of the response.
30 */
31 public class DoubleDotOutputStream extends FilterOutputStream {
32
33 // remember last 2 bytes written
34 final int[] buf = {0, 0};
35
36 public DoubleDotOutputStream(OutputStream out) {
37 super(out);
38 }
39
40 @Override
41 public void write(int b) throws IOException {
42 if (b == '.' && (buf[0] == '\r' || buf[0] == '\n' || buf[0] == 0)) {
43 // line starts with '.', prepend it with an additional '.'
44 out.write('.');
45 }
46 out.write(b);
47
48 buf[1] = buf[0];
49 buf[0] = b;
50 }
51
52 /**
53 * RFC 1939: 3 Basic Operations
54 * [...]
55 * Hence a multi-line response is terminated with the five octets
56 * "CRLF.CRLF"
57 * <p/>
58 * Do not close actual outputstream
59 *
60 * @throws IOException on error
61 */
62 @Override
63 public void close() throws IOException {
64 if (buf[1] != '\r' || buf[0] != '\n') {
65 out.write('\r');
66 out.write('\n');
67 }
68 out.write('.');
69 out.write('\r');
70 out.write('\n');
71 }
72
73 }