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.FilterOutputStream; 019 import java.io.IOException; 020 import java.io.OutputStream; 021 022 /*** 023 * This class wraps an output stream, replacing all occurrences 024 * of <CR><LF> (carriage return followed by a linefeed), 025 * which is the NETASCII standard for representing a newline, with the 026 * local line separator representation. You would use this class to 027 * implement ASCII file transfers requiring conversion from NETASCII. 028 * <p> 029 * Because of the translation process, a call to <code>flush()</code> will 030 * not flush the last byte written if that byte was a carriage 031 * return. A call to {@link #close close() }, however, will 032 * flush the carriage return. 033 * <p> 034 * <p> 035 * @author Daniel F. Savarese 036 ***/ 037 038 public final class FromNetASCIIOutputStream extends FilterOutputStream 039 { 040 private boolean __lastWasCR; 041 042 /*** 043 * Creates a FromNetASCIIOutputStream instance that wraps an existing 044 * OutputStream. 045 * <p> 046 * @param output The OutputStream to wrap. 047 ***/ 048 public FromNetASCIIOutputStream(OutputStream output) 049 { 050 super(output); 051 __lastWasCR = false; 052 } 053 054 055 private void __write(int ch) throws IOException 056 { 057 switch (ch) 058 { 059 case '\r': 060 __lastWasCR = true; 061 // Don't write anything. We need to see if next one is linefeed 062 break; 063 case '\n': 064 if (__lastWasCR) 065 { 066 out.write(FromNetASCIIInputStream._lineSeparatorBytes); 067 __lastWasCR = false; 068 break; 069 } 070 __lastWasCR = false; 071 out.write('\n'); 072 break; 073 default: 074 if (__lastWasCR) 075 { 076 out.write('\r'); 077 __lastWasCR = false; 078 } 079 out.write(ch); 080 break; 081 } 082 } 083 084 085 /*** 086 * Writes a byte to the stream. Note that a call to this method 087 * might not actually write a byte to the underlying stream until a 088 * subsequent character is written, from which it can be determined if 089 * a NETASCII line separator was encountered. 090 * This is transparent to the programmer and is only mentioned for 091 * completeness. 092 * <p> 093 * @param ch The byte to write. 094 * @exception IOException If an error occurs while writing to the underlying 095 * stream. 096 ***/ 097 public synchronized void write(int ch) 098 throws IOException 099 { 100 if (FromNetASCIIInputStream._noConversionRequired) 101 { 102 out.write(ch); 103 return ; 104 } 105 106 __write(ch); 107 } 108 109 110 /*** 111 * Writes a byte array to the stream. 112 * <p> 113 * @param buffer The byte array to write. 114 * @exception IOException If an error occurs while writing to the underlying 115 * stream. 116 ***/ 117 public synchronized void write(byte buffer[]) 118 throws IOException 119 { 120 write(buffer, 0, buffer.length); 121 } 122 123 124 /*** 125 * Writes a number of bytes from a byte array to the stream starting from 126 * a given offset. 127 * <p> 128 * @param buffer The byte array to write. 129 * @param offset The offset into the array at which to start copying data. 130 * @param length The number of bytes to write. 131 * @exception IOException If an error occurs while writing to the underlying 132 * stream. 133 ***/ 134 public synchronized void write(byte buffer[], int offset, int length) 135 throws IOException 136 { 137 if (FromNetASCIIInputStream._noConversionRequired) 138 { 139 // FilterOutputStream method is very slow. 140 //super.write(buffer, offset, length); 141 out.write(buffer, offset, length); 142 return ; 143 } 144 145 while (length-- > 0) 146 __write(buffer[offset++]); 147 } 148 149 150 /*** 151 * Closes the stream, writing all pending data. 152 * <p> 153 * @exception IOException If an error occurs while closing the stream. 154 ***/ 155 public synchronized void close() 156 throws IOException 157 { 158 if (FromNetASCIIInputStream._noConversionRequired) 159 { 160 super.close(); 161 return ; 162 } 163 164 if (__lastWasCR) 165 out.write('\r'); 166 super.close(); 167 } 168 }