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: private static final int __NOTHING_SPECIAL = 0;
036: private static final int __LAST_WAS_CR = 1;
037: private static final int __LAST_WAS_NL = 2;
038: private int __status;
039:
040: /***
041: * Creates a ToNetASCIIInputStream instance that wraps an existing
042: * InputStream.
043: * <p>
044: * @param input The InputStream to .
045: ***/
046: public ToNetASCIIInputStream(InputStream input) {
047: super (input);
048: __status = __NOTHING_SPECIAL;
049: }
050:
051: /***
052: * Reads and returns the next byte in the stream. If the end of the
053: * message has been reached, returns -1.
054: * <p>
055: * @return The next character in the stream. Returns -1 if the end of the
056: * stream has been reached.
057: * @exception IOException If an error occurs while reading the underlying
058: * stream.
059: ***/
060: public int read() throws IOException {
061: int ch;
062:
063: if (__status == __LAST_WAS_NL) {
064: __status = __NOTHING_SPECIAL;
065: return '\n';
066: }
067:
068: ch = in.read();
069:
070: switch (ch) {
071: case '\r':
072: __status = __LAST_WAS_CR;
073: return '\r';
074: case '\n':
075: if (__status != __LAST_WAS_CR) {
076: __status = __LAST_WAS_NL;
077: return '\r';
078: }
079: // else fall through
080: default:
081: __status = __NOTHING_SPECIAL;
082: return ch;
083: }
084: // statement not reached
085: //return ch;
086: }
087:
088: /***
089: * Reads the next number of bytes from the stream into an array and
090: * returns the number of bytes read. Returns -1 if the end of the
091: * stream has been reached.
092: * <p>
093: * @param buffer The byte array in which to store the data.
094: * @return The number of bytes read. Returns -1 if the
095: * end of the message has been reached.
096: * @exception IOException If an error occurs in reading the underlying
097: * stream.
098: ***/
099: public int read(byte buffer[]) throws IOException {
100: return read(buffer, 0, buffer.length);
101: }
102:
103: /***
104: * Reads the next number of bytes from the stream into an array and returns
105: * the number of bytes read. Returns -1 if the end of the
106: * message has been reached. The characters are stored in the array
107: * starting from the given offset and up to the length specified.
108: * <p>
109: * @param buffer The byte array in which to store the data.
110: * @param offset The offset into the array at which to start storing data.
111: * @param length The number of bytes to read.
112: * @return The number of bytes read. Returns -1 if the
113: * end of the stream has been reached.
114: * @exception IOException If an error occurs while reading the underlying
115: * stream.
116: ***/
117: public int read(byte buffer[], int offset, int length)
118: throws IOException {
119: int ch, off;
120:
121: if (length < 1)
122: return 0;
123:
124: ch = available();
125:
126: if (length > ch)
127: length = ch;
128:
129: // If nothing is available, block to read only one character
130: if (length < 1)
131: length = 1;
132:
133: if ((ch = read()) == -1)
134: return -1;
135:
136: off = offset;
137:
138: do {
139: buffer[offset++] = (byte) ch;
140: } while (--length > 0 && (ch = read()) != -1);
141:
142: return (offset - off);
143: }
144:
145: /*** Returns false. Mark is not supported. ***/
146: public boolean markSupported() {
147: return false;
148: }
149:
150: public int available() throws IOException {
151: int result;
152:
153: result = in.available();
154:
155: if (__status == __LAST_WAS_NL)
156: return (result + 1);
157:
158: return result;
159: }
160: }
|