1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.util.stream;
21
22 import java.io.FilterOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStream;
25
26
27
28
29
30
31
32
33
34
35 public class CRLFOutputStream extends FilterOutputStream {
36
37
38
39
40 protected int statusLast;
41
42 protected final static int LAST_WAS_OTHER = 0;
43
44 protected final static int LAST_WAS_CR = 1;
45
46 protected final static int LAST_WAS_LF = 2;
47
48 protected boolean startOfLine = true;
49
50
51
52
53
54
55
56 public CRLFOutputStream(OutputStream out) {
57 super(out);
58 statusLast = LAST_WAS_LF;
59
60
61 }
62
63
64
65
66
67
68
69
70
71
72
73 public void write(int b) throws IOException {
74 switch (b) {
75 case '\r':
76 out.write('\r');
77 out.write('\n');
78 startOfLine = true;
79 statusLast = LAST_WAS_CR;
80 break;
81 case '\n':
82 if (statusLast != LAST_WAS_CR) {
83 out.write('\r');
84 out.write('\n');
85 startOfLine = true;
86 }
87 statusLast = LAST_WAS_LF;
88 break;
89 default:
90
91 out.write(b);
92 startOfLine = false;
93 statusLast = LAST_WAS_OTHER;
94 break;
95 }
96 }
97
98
99
100
101
102
103
104 protected void writeChunk(byte buffer[], int offset, int length) throws IOException {
105 out.write(buffer, offset, length);
106 }
107
108
109
110
111 public synchronized void write(byte buffer[], int offset, int length)
112 throws IOException {
113
114 int lineStart = offset;
115 for (int i = offset; i < length + offset; i++) {
116 switch(buffer[i]) {
117 case '\r':
118
119
120 writeChunk(buffer, lineStart, i - lineStart);
121 out.write('\r');
122 out.write('\n');
123 startOfLine = true;
124 lineStart = i + 1;
125 statusLast = LAST_WAS_CR;
126 break;
127 case '\n':
128 if (statusLast != LAST_WAS_CR) {
129 writeChunk(buffer, lineStart, i - lineStart);
130 out.write('\r');
131 out.write('\n');
132 startOfLine = true;
133 }
134 lineStart = i + 1;
135 statusLast = LAST_WAS_LF;
136 break;
137 default:
138 statusLast = LAST_WAS_OTHER;
139 }
140 }
141 if (length + offset > lineStart) {
142 writeChunk(buffer, lineStart, length + offset - lineStart);
143 startOfLine = false;
144 }
145 }
146
147
148
149
150
151
152
153
154 public void checkCRLFTerminator() throws IOException {
155 if (statusLast == LAST_WAS_OTHER) {
156 out.write('\r');
157 out.write('\n');
158 statusLast = LAST_WAS_CR;
159 }
160 }
161 }