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 }