1. /*
  2. * Copyright 2001-2004 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. import java.io.FilterOutputStream;
  18. import java.io.IOException;
  19. import java.io.OutputStream;
  20. /***
  21. * This class wraps an output stream, replacing all occurrences
  22. * of <CR><LF> (carriage return followed by a linefeed),
  23. * which is the NETASCII standard for representing a newline, with the
  24. * local line separator representation. You would use this class to
  25. * implement ASCII file transfers requiring conversion from NETASCII.
  26. * <p>
  27. * Because of the translation process, a call to <code>flush()</code> will
  28. * not flush the last byte written if that byte was a carriage
  29. * return. A call to <a href="#close"> close() </a>, however, will
  30. * flush the carriage return.
  31. * <p>
  32. * <p>
  33. * @author Daniel F. Savarese
  34. ***/
  35. public final class FromNetASCIIOutputStream extends FilterOutputStream
  36. {
  37. private boolean __lastWasCR;
  38. /***
  39. * Creates a FromNetASCIIOutputStream instance that wraps an existing
  40. * OutputStream.
  41. * <p>
  42. * @param output The OutputStream to wrap.
  43. ***/
  44. public FromNetASCIIOutputStream(OutputStream output)
  45. {
  46. super(output);
  47. __lastWasCR = false;
  48. }
  49. private void __write(int ch) throws IOException
  50. {
  51. switch (ch)
  52. {
  53. case '\r':
  54. __lastWasCR = true;
  55. // Don't write anything. We need to see if next one is linefeed
  56. break;
  57. case '\n':
  58. if (__lastWasCR)
  59. {
  60. out.write(FromNetASCIIInputStream._lineSeparatorBytes);
  61. __lastWasCR = false;
  62. break;
  63. }
  64. __lastWasCR = false;
  65. out.write('\n');
  66. break;
  67. default:
  68. if (__lastWasCR)
  69. {
  70. out.write('\r');
  71. __lastWasCR = false;
  72. }
  73. out.write(ch);
  74. break;
  75. }
  76. }
  77. /***
  78. * Writes a byte to the stream. Note that a call to this method
  79. * might not actually write a byte to the underlying stream until a
  80. * subsequent character is written, from which it can be determined if
  81. * a NETASCII line separator was encountered.
  82. * This is transparent to the programmer and is only mentioned for
  83. * completeness.
  84. * <p>
  85. * @param ch The byte to write.
  86. * @exception IOException If an error occurs while writing to the underlying
  87. * stream.
  88. ***/
  89. public synchronized void write(int ch)
  90. throws IOException
  91. {
  92. if (FromNetASCIIInputStream._noConversionRequired)
  93. {
  94. out.write(ch);
  95. return ;
  96. }
  97. __write(ch);
  98. }
  99. /***
  100. * Writes a byte array to the stream.
  101. * <p>
  102. * @param buffer The byte array to write.
  103. * @exception IOException If an error occurs while writing to the underlying
  104. * stream.
  105. ***/
  106. public synchronized void write(byte buffer[])
  107. throws IOException
  108. {
  109. write(buffer, 0, buffer.length);
  110. }
  111. /***
  112. * Writes a number of bytes from a byte array to the stream starting from
  113. * a given offset.
  114. * <p>
  115. * @param buffer The byte array to write.
  116. * @param offset The offset into the array at which to start copying data.
  117. * @param length The number of bytes to write.
  118. * @exception IOException If an error occurs while writing to the underlying
  119. * stream.
  120. ***/
  121. public synchronized void write(byte buffer[], int offset, int length)
  122. throws IOException
  123. {
  124. if (FromNetASCIIInputStream._noConversionRequired)
  125. {
  126. // FilterOutputStream method is very slow.
  127. //super.write(buffer, offset, length);
  128. out.write(buffer, offset, length);
  129. return ;
  130. }
  131. while (length-- > 0)
  132. __write(buffer[offset++]);
  133. }
  134. /***
  135. * Closes the stream, writing all pending data.
  136. * <p>
  137. * @exception IOException If an error occurs while closing the stream.
  138. ***/
  139. public synchronized void close()
  140. throws IOException
  141. {
  142. if (FromNetASCIIInputStream._noConversionRequired)
  143. {
  144. super.close();
  145. return ;
  146. }
  147. if (__lastWasCR)
  148. out.write('\r');
  149. super.close();
  150. }
  151. }