1 package org.apache.commons.net.io;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Commons" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.io.IOException;
58 import java.io.Writer;
59
60 /****
61 * DotTerminatedMessageWriter is a class used to write messages to a
62 * server that are terminated by a single dot followed by a
63 * <CR><LF>
64 * sequence and with double dots appearing at the begining of lines which
65 * do not signal end of message yet start with a dot. Various Internet
66 * protocols such as NNTP and POP3 produce messages of this type.
67 * <p>
68 * This class handles the doubling of line-starting periods,
69 * converts single linefeeds to NETASCII newlines, and on closing
70 * will send the final message terminator dot and NETASCII newline
71 * sequence.
72 * <p>
73 * <p>
74 * @author Daniel F. Savarese
75 ***/
76
77 public final class DotTerminatedMessageWriter extends Writer
78 {
79 private static final int __NOTHING_SPECIAL_STATE = 0;
80 private static final int __LAST_WAS_CR_STATE = 1;
81 private static final int __LAST_WAS_NL_STATE = 2;
82
83 private int __state;
84 private Writer __output;
85
86
87 /****
88 * Creates a DotTerminatedMessageWriter that wraps an existing Writer
89 * output destination.
90 * <p>
91 * @param output The Writer output destination to write the message.
92 ***/
93 public DotTerminatedMessageWriter(Writer output)
94 {
95 super(output);
96 __output = output;
97 __state = __NOTHING_SPECIAL_STATE;
98 }
99
100
101 /****
102 * Writes a character to the output. Note that a call to this method
103 * may result in multiple writes to the underling Writer in order to
104 * convert naked linefeeds to NETASCII line separators and to double
105 * line-leading periods. This is transparent to the programmer and
106 * is only mentioned for completeness.
107 * <p>
108 * @param ch The character to write.
109 * @exception IOException If an error occurs while writing to the
110 * underlying output.
111 ***/
112 public void write(int ch) throws IOException
113 {
114 synchronized (lock)
115 {
116 switch (ch)
117 {
118 case '\r':
119 __state = __LAST_WAS_CR_STATE;
120 __output.write('\r');
121 return ;
122 case '\n':
123 if (__state != __LAST_WAS_CR_STATE)
124 __output.write('\r');
125 __output.write('\n');
126 __state = __LAST_WAS_NL_STATE;
127 return ;
128 case '.':
129 // Double the dot at the beginning of a line
130 if (__state == __LAST_WAS_NL_STATE)
131 __output.write('.');
132 // Fall through
133 default:
134 __state = __NOTHING_SPECIAL_STATE;
135 __output.write(ch);
136 return ;
137 }
138 }
139 }
140
141
142 /****
143 * Writes a number of characters from a character array to the output
144 * starting from a given offset.
145 * <p>
146 * @param buffer The character array to write.
147 * @param offset The offset into the array at which to start copying data.
148 * @param length The number of characters to write.
149 * @exception IOException If an error occurs while writing to the underlying
150 * output.
151 ***/
152 public void write(char[] buffer, int offset, int length) throws IOException
153 {
154 synchronized (lock)
155 {
156 while (length-- > 0)
157 write(buffer[offset++]);
158 }
159 }
160
161
162 /****
163 * Writes a character array to the output.
164 * <p>
165 * @param buffer The character array to write.
166 * @exception IOException If an error occurs while writing to the underlying
167 * output.
168 ***/
169 public void write(char[] buffer) throws IOException
170 {
171 write(buffer, 0, buffer.length);
172 }
173
174
175 /****
176 * Writes a String to the output.
177 * <p>
178 * @param string The String to write.
179 * @exception IOException If an error occurs while writing to the underlying
180 * output.
181 ***/
182 public void write(String string) throws IOException
183 {
184 write(string.toCharArray());
185 }
186
187
188 /****
189 * Writes part of a String to the output starting from a given offset.
190 * <p>
191 * @param string The String to write.
192 * @param offset The offset into the String at which to start copying data.
193 * @param length The number of characters to write.
194 * @exception IOException If an error occurs while writing to the underlying
195 * output.
196 ***/
197 public void write(String string, int offset, int length) throws IOException
198 {
199 write(string.toCharArray(), offset, length);
200 }
201
202
203 /****
204 * Flushes the underlying output, writing all buffered output.
205 * <p>
206 * @exception IOException If an error occurs while writing to the underlying
207 * output.
208 ***/
209 public void flush() throws IOException
210 {
211 synchronized (lock)
212 {
213 __output.flush();
214 }
215 }
216
217
218 /****
219 * Flushes the underlying output, writing all buffered output, but doesn't
220 * actually close the underlying stream. The underlying stream may still
221 * be used for communicating with the server and therefore is not closed.
222 * <p>
223 * @exception IOException If an error occurs while writing to the underlying
224 * output or closing the Writer.
225 ***/
226 public void close() throws IOException
227 {
228 synchronized (lock)
229 {
230 if (__output == null)
231 return ;
232
233 if (__state == __LAST_WAS_CR_STATE)
234 __output.write('\n');
235 else if (__state != __LAST_WAS_NL_STATE)
236 __output.write("\r\n");
237
238 __output.write(".\r\n");
239
240 __output.flush();
241 __output = null;
242 }
243 }
244
245 }
This page was automatically generated by Maven