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 }