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 &lt;CR&gt;&lt;LF&gt; (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 }