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   * <LF> (linefeed) characters with <CR><LF> (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 }