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.FilterInputStream;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. /***
  21. * This class wraps an input stream, replacing all singly occurring
  22. * <LF> (linefeed) characters with <CR><LF> (carriage return
  23. * followed by linefeed), which is the NETASCII standard for representing
  24. * a newline.
  25. * You would use this class to implement ASCII file transfers requiring
  26. * conversion to NETASCII.
  27. * <p>
  28. * <p>
  29. * @author Daniel F. Savarese
  30. ***/
  31. public final class ToNetASCIIInputStream extends FilterInputStream
  32. {
  33. private static final int __NOTHING_SPECIAL = 0;
  34. private static final int __LAST_WAS_CR = 1;
  35. private static final int __LAST_WAS_NL = 2;
  36. private int __status;
  37. /***
  38. * Creates a ToNetASCIIInputStream instance that wraps an existing
  39. * InputStream.
  40. * <p>
  41. * @param input The InputStream to .
  42. ***/
  43. public ToNetASCIIInputStream(InputStream input)
  44. {
  45. super(input);
  46. __status = __NOTHING_SPECIAL;
  47. }
  48. /***
  49. * Reads and returns the next byte in the stream. If the end of the
  50. * message has been reached, returns -1.
  51. * <p>
  52. * @return The next character in the stream. Returns -1 if the end of the
  53. * stream has been reached.
  54. * @exception IOException If an error occurs while reading the underlying
  55. * stream.
  56. ***/
  57. public int read() throws IOException
  58. {
  59. int ch;
  60. if (__status == __LAST_WAS_NL)
  61. {
  62. __status = __NOTHING_SPECIAL;
  63. return '\n';
  64. }
  65. ch = in.read();
  66. switch (ch)
  67. {
  68. case '\r':
  69. __status = __LAST_WAS_CR;
  70. return '\r';
  71. case '\n':
  72. if (__status != __LAST_WAS_CR)
  73. {
  74. __status = __LAST_WAS_NL;
  75. return '\r';
  76. }
  77. // else fall through
  78. default:
  79. __status = __NOTHING_SPECIAL;
  80. return ch;
  81. }
  82. // statement not reached
  83. //return ch;
  84. }
  85. /***
  86. * Reads the next number of bytes from the stream into an array and
  87. * returns the number of bytes read. Returns -1 if the end of the
  88. * stream has been reached.
  89. * <p>
  90. * @param buffer The byte array in which to store the data.
  91. * @return The number of bytes read. Returns -1 if the
  92. * end of the message has been reached.
  93. * @exception IOException If an error occurs in reading the underlying
  94. * stream.
  95. ***/
  96. public int read(byte buffer[]) throws IOException
  97. {
  98. return read(buffer, 0, buffer.length);
  99. }
  100. /***
  101. * Reads the next number of bytes from the stream into an array and returns
  102. * the number of bytes read. Returns -1 if the end of the
  103. * message has been reached. The characters are stored in the array
  104. * starting from the given offset and up to the length specified.
  105. * <p>
  106. * @param buffer The byte array in which to store the data.
  107. * @param offset The offset into the array at which to start storing data.
  108. * @param length The number of bytes to read.
  109. * @return The number of bytes read. Returns -1 if the
  110. * end of the stream has been reached.
  111. * @exception IOException If an error occurs while reading the underlying
  112. * stream.
  113. ***/
  114. public int read(byte buffer[], int offset, int length) throws IOException
  115. {
  116. int ch, off;
  117. if (length < 1)
  118. return 0;
  119. ch = available();
  120. if (length > ch)
  121. length = ch;
  122. // If nothing is available, block to read only one character
  123. if (length < 1)
  124. length = 1;
  125. if ((ch = read()) == -1)
  126. return -1;
  127. off = offset;
  128. do
  129. {
  130. buffer[offset++] = (byte)ch;
  131. }
  132. while (--length > 0 && (ch = read()) != -1);
  133. return (offset - off);
  134. }
  135. /*** Returns false. Mark is not supported. ***/
  136. public boolean markSupported()
  137. {
  138. return false;
  139. }
  140. public int available() throws IOException
  141. {
  142. int result;
  143. result = in.available();
  144. if (__status == __LAST_WAS_NL)
  145. return (result + 1);
  146. return result;
  147. }
  148. }