1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.net.io;
17
18 import java.io.FilterOutputStream;
19 import java.io.IOException;
20 import java.io.OutputStream;
21
22 /***
23 * This class wraps an output stream, replacing all occurrences
24 * of <CR><LF> (carriage return followed by a linefeed),
25 * which is the NETASCII standard for representing a newline, with the
26 * local line separator representation. You would use this class to
27 * implement ASCII file transfers requiring conversion from NETASCII.
28 * <p>
29 * Because of the translation process, a call to <code>flush()</code> will
30 * not flush the last byte written if that byte was a carriage
31 * return. A call to {@link #close close() }, however, will
32 * flush the carriage return.
33 * <p>
34 * <p>
35 * @author Daniel F. Savarese
36 ***/
37
38 public final class FromNetASCIIOutputStream extends FilterOutputStream
39 {
40 private boolean __lastWasCR;
41
42 /***
43 * Creates a FromNetASCIIOutputStream instance that wraps an existing
44 * OutputStream.
45 * <p>
46 * @param output The OutputStream to wrap.
47 ***/
48 public FromNetASCIIOutputStream(OutputStream output)
49 {
50 super(output);
51 __lastWasCR = false;
52 }
53
54
55 private void __write(int ch) throws IOException
56 {
57 switch (ch)
58 {
59 case '\r':
60 __lastWasCR = true;
61
62 break;
63 case '\n':
64 if (__lastWasCR)
65 {
66 out.write(FromNetASCIIInputStream._lineSeparatorBytes);
67 __lastWasCR = false;
68 break;
69 }
70 __lastWasCR = false;
71 out.write('\n');
72 break;
73 default:
74 if (__lastWasCR)
75 {
76 out.write('\r');
77 __lastWasCR = false;
78 }
79 out.write(ch);
80 break;
81 }
82 }
83
84
85 /***
86 * Writes a byte to the stream. Note that a call to this method
87 * might not actually write a byte to the underlying stream until a
88 * subsequent character is written, from which it can be determined if
89 * a NETASCII line separator was encountered.
90 * This is transparent to the programmer and is only mentioned for
91 * completeness.
92 * <p>
93 * @param ch The byte to write.
94 * @exception IOException If an error occurs while writing to the underlying
95 * stream.
96 ***/
97 public synchronized void write(int ch)
98 throws IOException
99 {
100 if (FromNetASCIIInputStream._noConversionRequired)
101 {
102 out.write(ch);
103 return ;
104 }
105
106 __write(ch);
107 }
108
109
110 /***
111 * Writes a byte array to the stream.
112 * <p>
113 * @param buffer The byte array to write.
114 * @exception IOException If an error occurs while writing to the underlying
115 * stream.
116 ***/
117 public synchronized void write(byte buffer[])
118 throws IOException
119 {
120 write(buffer, 0, buffer.length);
121 }
122
123
124 /***
125 * Writes a number of bytes from a byte array to the stream starting from
126 * a given offset.
127 * <p>
128 * @param buffer The byte array to write.
129 * @param offset The offset into the array at which to start copying data.
130 * @param length The number of bytes to write.
131 * @exception IOException If an error occurs while writing to the underlying
132 * stream.
133 ***/
134 public synchronized void write(byte buffer[], int offset, int length)
135 throws IOException
136 {
137 if (FromNetASCIIInputStream._noConversionRequired)
138 {
139
140
141 out.write(buffer, offset, length);
142 return ;
143 }
144
145 while (length-- > 0)
146 __write(buffer[offset++]);
147 }
148
149
150 /***
151 * Closes the stream, writing all pending data.
152 * <p>
153 * @exception IOException If an error occurs while closing the stream.
154 ***/
155 public synchronized void close()
156 throws IOException
157 {
158 if (FromNetASCIIInputStream._noConversionRequired)
159 {
160 super.close();
161 return ;
162 }
163
164 if (__lastWasCR)
165 out.write('\r');
166 super.close();
167 }
168 }