View Javadoc

1   /*
2    * Copyright 2001-2005 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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              // Don't write anything.  We need to see if next one is linefeed
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             // FilterOutputStream method is very slow.
140             //super.write(buffer, offset, length);
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 }