1. /*
  2. * @(#)SocketInputStream.java 1.23 00/02/02
  3. *
  4. * Copyright 1995-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.net;
  11. import java.io.IOException;
  12. import java.io.FileInputStream;
  13. /**
  14. * This stream extends FileInputStream to implement a
  15. * SocketInputStream. Note that this class should <b>NOT</b> be
  16. * public.
  17. *
  18. * @version 1.23, 02/02/00
  19. * @author Jonathan Payne
  20. * @author Arthur van Hoff
  21. */
  22. class SocketInputStream extends FileInputStream
  23. {
  24. static {
  25. init();
  26. }
  27. private boolean eof;
  28. private SocketImpl impl;
  29. private byte temp[];
  30. /**
  31. * Creates a new SocketInputStream. Can only be called
  32. * by a Socket. This method needs to hang on to the owner Socket so
  33. * that the fd will not be closed.
  34. * @param impl the implemented socket input stream
  35. */
  36. SocketInputStream(SocketImpl impl) throws IOException {
  37. super(impl.getFileDescriptor());
  38. this.impl = impl;
  39. }
  40. /**
  41. * Reads into an array of bytes at the specified offset using
  42. * the received socket primitive.
  43. * @param b the buffer into which the data is read
  44. * @param off the start offset of the data
  45. * @param len the maximum number of bytes read
  46. * @return the actual number of bytes read, -1 is
  47. * returned when the end of the stream is reached.
  48. * @exception IOException If an I/O error has occurred.
  49. */
  50. private native int socketRead(byte b[], int off, int len)
  51. throws IOException;
  52. /**
  53. * Reads into a byte array data from the socket.
  54. * @param b the buffer into which the data is read
  55. * @return the actual number of bytes read, -1 is
  56. * returned when the end of the stream is reached.
  57. * @exception IOException If an I/O error has occurred.
  58. */
  59. public int read(byte b[]) throws IOException {
  60. return read(b, 0, b.length);
  61. }
  62. /**
  63. * Reads into a byte array <i>b</i> at offset <i>off</i>,
  64. * <i>length</i> bytes of data.
  65. * @param b the buffer into which the data is read
  66. * @param off the start offset of the data
  67. * @param len the maximum number of bytes read
  68. * @return the actual number of bytes read, -1 is
  69. * returned when the end of the stream is reached.
  70. * @exception IOException If an I/O error has occurred.
  71. */
  72. public int read(byte b[], int off, int length) throws IOException {
  73. if (eof) {
  74. return -1;
  75. }
  76. if (length == 0)
  77. return 0;
  78. int n = socketRead(b, off, length);
  79. if (n <= 0) {
  80. eof = true;
  81. return -1;
  82. }
  83. return n;
  84. }
  85. /**
  86. * Reads a single byte from the socket.
  87. */
  88. public int read() throws IOException {
  89. if (eof) {
  90. return -1;
  91. }
  92. temp = new byte[1];
  93. int n = read(temp, 0, 1);
  94. if (n <= 0) {
  95. return -1;
  96. }
  97. return temp[0] & 0xff;
  98. }
  99. /**
  100. * Skips n bytes of input.
  101. * @param n the number of bytes to skip
  102. * @return the actual number of bytes skipped.
  103. * @exception IOException If an I/O error has occurred.
  104. */
  105. public long skip(long numbytes) throws IOException {
  106. if (numbytes <= 0) {
  107. return 0;
  108. }
  109. long n = numbytes;
  110. int buflen = (int) Math.min(1024, n);
  111. byte data[] = new byte[buflen];
  112. while (n > 0) {
  113. int r = read(data, 0, (int) Math.min((long) buflen, n));
  114. if (r < 0) {
  115. break;
  116. }
  117. n -= r;
  118. }
  119. return numbytes - n;
  120. }
  121. /**
  122. * Returns the number of bytes that can be read without blocking.
  123. * @return the number of immediately available bytes
  124. */
  125. public int available() throws IOException {
  126. return impl.available();
  127. }
  128. /**
  129. * Closes the stream.
  130. */
  131. public void close() throws IOException {
  132. impl.close();
  133. }
  134. void setEOF(boolean eof) {
  135. this.eof = eof;
  136. }
  137. /**
  138. * Overrides finalize, the fd is closed by the Socket.
  139. */
  140. protected void finalize() {}
  141. /**
  142. * Perform class load-time initializations.
  143. */
  144. private native static void init();
  145. }