1 /************************************************************************
2 * Copyright (c) 2000-2006 The Apache Software Foundation. *
3 * All rights reserved. *
4 * ------------------------------------------------------------------- *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you *
6 * may not use this file except in compliance with the License. You *
7 * may obtain a copy of the License at: *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14 * implied. See the License for the specific language governing *
15 * permissions and limitations under the License. *
16 ***********************************************************************/
17
18 package org.apache.james.util;
19
20 import java.io.FilterOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStream;
23
24 /***
25 * Adds extra dot if dot occurs in message body at beginning of line (according to RFC1939)
26 * Compare also org.apache.james.smtpserver.SMTPInputStream
27 */
28 public class ExtraDotOutputStream extends FilterOutputStream {
29
30
31
32
33
34
35
36
37
38
39
40 /***
41 * Counter for number of last (0A or 0D).
42 */
43 protected int countLast0A0D;
44
45 /***
46 * Constructor that wraps an OutputStream.
47 *
48 * @param out the OutputStream to be wrapped
49 */
50 public ExtraDotOutputStream(OutputStream out) {
51 super(out);
52 countLast0A0D = 2;
53 }
54
55 /***
56 * Writes a byte to the stream, adding dots where appropriate.
57 * Also fixes any naked CR or LF to the RFC 2821 mandated CFLF
58 * pairing.
59 *
60 * @param b the byte to write
61 *
62 * @throws IOException if an error occurs writing the byte
63 */
64 public void write(int b) throws IOException {
65 switch (b) {
66 case '.':
67 if (countLast0A0D == 2) {
68
69 out.write('.');
70 }
71 countLast0A0D = 0;
72 break;
73 case '\r':
74 if (countLast0A0D == 1) out.write('\n');
75 countLast0A0D = 1;
76 break;
77 case '\n':
78
79
80
81
82
83 if (countLast0A0D != 1) out.write('\r');
84 countLast0A0D = 2;
85 break;
86 default:
87
88 countLast0A0D = 0;
89 break;
90 }
91 out.write(b);
92 }
93
94 /***
95 * Ensure that the stream is CRLF terminated.
96 *
97 * @throws IOException if an error occurs writing the byte
98 */
99 public void checkCRLFTerminator() throws IOException {
100 if (countLast0A0D != 2) {
101 write('\n');
102 }
103 }
104 }