001    /*
002     * Copyright 2001-2005 The Apache Software Foundation
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.commons.net.io;
017    
018    import java.io.FilterInputStream;
019    import java.io.IOException;
020    import java.io.InputStream;
021    
022    /***
023     * This class wraps an input stream, replacing all singly occurring
024     * <LF> (linefeed) characters with <CR><LF> (carriage return
025     * followed by linefeed), which is the NETASCII standard for representing
026     * a newline.
027     * You would use this class to implement ASCII file transfers requiring
028     * conversion to NETASCII.
029     * <p>
030     * <p>
031     * @author Daniel F. Savarese
032     ***/
033    
034    public final class ToNetASCIIInputStream extends FilterInputStream
035    {
036        private static final int __NOTHING_SPECIAL = 0;
037        private static final int __LAST_WAS_CR = 1;
038        private static final int __LAST_WAS_NL = 2;
039        private int __status;
040    
041        /***
042         * Creates a ToNetASCIIInputStream instance that wraps an existing
043         * InputStream.
044         * <p>
045         * @param input  The InputStream to .
046         ***/
047        public ToNetASCIIInputStream(InputStream input)
048        {
049            super(input);
050            __status = __NOTHING_SPECIAL;
051        }
052    
053    
054        /***
055         * Reads and returns the next byte in the stream.  If the end of the
056         * message has been reached, returns -1.
057         * <p>
058         * @return The next character in the stream. Returns -1 if the end of the
059         *          stream has been reached.
060         * @exception IOException If an error occurs while reading the underlying
061         *            stream.
062         ***/
063        public int read() throws IOException
064        {
065            int ch;
066    
067            if (__status == __LAST_WAS_NL)
068            {
069                __status = __NOTHING_SPECIAL;
070                return '\n';
071            }
072    
073            ch = in.read();
074    
075            switch (ch)
076            {
077            case '\r':
078                __status = __LAST_WAS_CR;
079                return '\r';
080            case '\n':
081                if (__status != __LAST_WAS_CR)
082                {
083                    __status = __LAST_WAS_NL;
084                    return '\r';
085                }
086                // else fall through
087            default:
088                __status = __NOTHING_SPECIAL;
089                return ch;
090            }
091            // statement not reached
092            //return ch;
093        }
094    
095    
096        /***
097         * Reads the next number of bytes from the stream into an array and
098         * returns the number of bytes read.  Returns -1 if the end of the
099         * 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    }