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.FilterInputStream;
    19  import java.io.IOException;
    20  import java.io.InputStream;
    21
    22  /****
    23   * This class wraps an input stream, replacing all singly occurring
    24   * &lt;LF&gt; (linefeed) characters with &lt;CR&gt;&lt;LF&gt; (carriage return
    25   * followed by linefeed), which is the NETASCII standard for representing
    26   * a newline.
    27   * You would use this class to implement ASCII file transfers requiring
    28   * conversion to NETASCII.
    29   * <p>
    30   * <p>
    31   * @author Daniel F. Savarese
    32   ***/
    33
    34  public final class ToNetASCIIInputStream extends FilterInputStream
    35  {
    36      private static final int __NOTHING_SPECIAL = 0;
    37      private static final int __LAST_WAS_CR = 1;
    38      private static final int __LAST_WAS_NL = 2;
    39      private int __status;
    40
    41      /****
    42       * Creates a ToNetASCIIInputStream instance that wraps an existing
    43       * InputStream.
    44       * <p>
    45       * @param input  The InputStream to .
    46       ***/
    47      public ToNetASCIIInputStream(InputStream input)
    48      {
    49          super(input);
    50          __status = __NOTHING_SPECIAL;
    51      }
    52
    53
    54      /****
    55       * Reads and returns the next byte in the stream.  If the end of the
    56       * message has been reached, returns -1.
    57       * <p>
    58       * @return The next character in the stream. Returns -1 if the end of the
    59       *          stream has been reached.
    60       * @exception IOException If an error occurs while reading the underlying
    61       *            stream.
    62       ***/
    63      public int read() throws IOException
    64      {
    65          int ch;
    66
    67          if (__status == __LAST_WAS_NL)
    68          {
    69              __status = __NOTHING_SPECIAL;
    70              return '\n';
    71          }
    72
    73          ch = in.read();
    74
    75          switch (ch)
    76          {
    77          case '\r':
    78              __status = __LAST_WAS_CR;
    79              return '\r';
    80          case '\n':
    81              if (__status != __LAST_WAS_CR)
    82              {
    83                  __status = __LAST_WAS_NL;
    84                  return '\r';
    85              }
    86              // else fall through
    87          default:
    88              __status = __NOTHING_SPECIAL;
    89              return ch;
    90          }
    91          // statement not reached
    92          //return ch;
    93      }
    94
    95
    96      /****
    97       * Reads the next number of bytes from the stream into an array and
    98       * returns the number of bytes read.  Returns -1 if the end of the
    99       * stream has been reached.
    100      * <p>
    101      * @param buffer  The byte array in which to store the data.
    102      * @return The number of bytes read. Returns -1 if the
    103      *          end of the message has been reached.
    104      * @exception IOException If an error occurs in reading the underlying
    105      *            stream.
    106      ***/
    107     public int read(byte buffer[]) throws IOException
    108     {
    109         return read(buffer, 0, buffer.length);
    110     }
    111
    112
    113     /****
    114      * Reads the next number of bytes from the stream into an array and returns
    115      * the number of bytes read.  Returns -1 if the end of the
    116      * message has been reached.  The characters are stored in the array
    117      * starting from the given offset and up to the length specified.
    118      * <p>
    119      * @param buffer The byte array in which to store the data.
    120      * @param offset  The offset into the array at which to start storing data.
    121      * @param length   The number of bytes to read.
    122      * @return The number of bytes read. Returns -1 if the
    123      *          end of the stream has been reached.
    124      * @exception IOException If an error occurs while reading the underlying
    125      *            stream.
    126      ***/
    127     public int read(byte buffer[], int offset, int length) throws IOException
    128     {
    129         int ch, off;
    130
    131         if (length < 1)
    132             return 0;
    133
    134         ch = available();
    135
    136         if (length > ch)
    137             length = ch;
    138
    139         // If nothing is available, block to read only one character
    140         if (length < 1)
    141             length = 1;
    142
    143         if ((ch = read()) == -1)
    144             return -1;
    145
    146         off = offset;
    147
    148         do
    149         {
    150             buffer[offset++] = (byte)ch;
    151         }
    152         while (--length > 0 && (ch = read()) != -1);
    153
    154         return (offset - off);
    155     }
    156
    157     /**** Returns false.  Mark is not supported. ***/
    158     public boolean markSupported()
    159     {
    160         return false;
    161     }
    162
    163     public int available() throws IOException
    164     {
    165         int result;
    166
    167         result = in.available();
    168
    169         if (__status == __LAST_WAS_NL)
    170             return (result + 1);
    171
    172         return result;
    173     }
    174 }