Save This Page
Home » apache-harmony-6.0-src-r917296-snapshot » java » net » [javadoc | source]
    1   /*
    2    * Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.net;
   27   
   28   import java.io.FileDescriptor;
   29   import java.io.FileInputStream;
   30   import java.io.IOException;
   31   import java.nio.channels.FileChannel;
   32   
   33   import sun.net.ConnectionResetException;
   34   
   35   /**
   36    * This stream extends FileInputStream to implement a
   37    * SocketInputStream. Note that this class should <b>NOT</b> be
   38    * public.
   39    *
   40    * @author      Jonathan Payne
   41    * @author      Arthur van Hoff
   42    */
   43   class SocketInputStream extends FileInputStream
   44   {
   45       static {
   46           init();
   47       }
   48   
   49       private boolean eof;
   50       private AbstractPlainSocketImpl impl = null;
   51       private byte temp[];
   52       private Socket socket = null;
   53   
   54       /**
   55        * Creates a new SocketInputStream. Can only be called
   56        * by a Socket. This method needs to hang on to the owner Socket so
   57        * that the fd will not be closed.
   58        * @param impl the implemented socket input stream
   59        */
   60       SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
   61           super(impl.getFileDescriptor());
   62           this.impl = impl;
   63           socket = impl.getSocket();
   64       }
   65   
   66       /**
   67        * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
   68        * object associated with this file input stream.</p>
   69        *
   70        * The <code>getChannel</code> method of <code>SocketInputStream</code>
   71        * returns <code>null</code> since it is a socket based stream.</p>
   72        *
   73        * @return  the file channel associated with this file input stream
   74        *
   75        * @since 1.4
   76        * @spec JSR-51
   77        */
   78       public final FileChannel getChannel() {
   79           return null;
   80       }
   81   
   82       /**
   83        * Reads into an array of bytes at the specified offset using
   84        * the received socket primitive.
   85        * @param fd the FileDescriptor
   86        * @param b the buffer into which the data is read
   87        * @param off the start offset of the data
   88        * @param len the maximum number of bytes read
   89        * @param timeout the read timeout in ms
   90        * @return the actual number of bytes read, -1 is
   91        *          returned when the end of the stream is reached.
   92        * @exception IOException If an I/O error has occurred.
   93        */
   94       private native int socketRead0(FileDescriptor fd,
   95                                      byte b[], int off, int len,
   96                                      int timeout)
   97           throws IOException;
   98   
   99       /**
  100        * Reads into a byte array data from the socket.
  101        * @param b the buffer into which the data is read
  102        * @return the actual number of bytes read, -1 is
  103        *          returned when the end of the stream is reached.
  104        * @exception IOException If an I/O error has occurred.
  105        */
  106       public int read(byte b[]) throws IOException {
  107           return read(b, 0, b.length);
  108       }
  109   
  110       /**
  111        * Reads into a byte array <i>b</i> at offset <i>off</i>,
  112        * <i>length</i> bytes of data.
  113        * @param b the buffer into which the data is read
  114        * @param off the start offset of the data
  115        * @param len the maximum number of bytes read
  116        * @return the actual number of bytes read, -1 is
  117        *          returned when the end of the stream is reached.
  118        * @exception IOException If an I/O error has occurred.
  119        */
  120       public int read(byte b[], int off, int length) throws IOException {
  121           int n;
  122   
  123           // EOF already encountered
  124           if (eof) {
  125               return -1;
  126           }
  127   
  128           // connection reset
  129           if (impl.isConnectionReset()) {
  130               throw new SocketException("Connection reset");
  131           }
  132   
  133           // bounds check
  134           if (length <= 0 || off < 0 || off + length > b.length) {
  135               if (length == 0) {
  136                   return 0;
  137               }
  138               throw new ArrayIndexOutOfBoundsException();
  139           }
  140   
  141           boolean gotReset = false;
  142   
  143           // acquire file descriptor and do the read
  144           FileDescriptor fd = impl.acquireFD();
  145           try {
  146               n = socketRead0(fd, b, off, length, impl.getTimeout());
  147               if (n > 0) {
  148                   return n;
  149               }
  150           } catch (ConnectionResetException rstExc) {
  151               gotReset = true;
  152           } finally {
  153               impl.releaseFD();
  154           }
  155   
  156           /*
  157            * We receive a "connection reset" but there may be bytes still
  158            * buffered on the socket
  159            */
  160           if (gotReset) {
  161               impl.setConnectionResetPending();
  162               impl.acquireFD();
  163               try {
  164                   n = socketRead0(fd, b, off, length, impl.getTimeout());
  165                   if (n > 0) {
  166                       return n;
  167                   }
  168               } catch (ConnectionResetException rstExc) {
  169               } finally {
  170                   impl.releaseFD();
  171               }
  172           }
  173   
  174           /*
  175            * If we get here we are at EOF, the socket has been closed,
  176            * or the connection has been reset.
  177            */
  178           if (impl.isClosedOrPending()) {
  179               throw new SocketException("Socket closed");
  180           }
  181           if (impl.isConnectionResetPending()) {
  182               impl.setConnectionReset();
  183           }
  184           if (impl.isConnectionReset()) {
  185               throw new SocketException("Connection reset");
  186           }
  187           eof = true;
  188           return -1;
  189       }
  190   
  191       /**
  192        * Reads a single byte from the socket.
  193        */
  194       public int read() throws IOException {
  195           if (eof) {
  196               return -1;
  197           }
  198           temp = new byte[1];
  199           int n = read(temp, 0, 1);
  200           if (n <= 0) {
  201               return -1;
  202           }
  203           return temp[0] & 0xff;
  204       }
  205   
  206       /**
  207        * Skips n bytes of input.
  208        * @param n the number of bytes to skip
  209        * @return  the actual number of bytes skipped.
  210        * @exception IOException If an I/O error has occurred.
  211        */
  212       public long skip(long numbytes) throws IOException {
  213           if (numbytes <= 0) {
  214               return 0;
  215           }
  216           long n = numbytes;
  217           int buflen = (int) Math.min(1024, n);
  218           byte data[] = new byte[buflen];
  219           while (n > 0) {
  220               int r = read(data, 0, (int) Math.min((long) buflen, n));
  221               if (r < 0) {
  222                   break;
  223               }
  224               n -= r;
  225           }
  226           return numbytes - n;
  227       }
  228   
  229       /**
  230        * Returns the number of bytes that can be read without blocking.
  231        * @return the number of immediately available bytes
  232        */
  233       public int available() throws IOException {
  234           return impl.available();
  235       }
  236   
  237       /**
  238        * Closes the stream.
  239        */
  240       private boolean closing = false;
  241       public void close() throws IOException {
  242           // Prevent recursion. See BugId 4484411
  243           if (closing)
  244               return;
  245           closing = true;
  246           if (socket != null) {
  247               if (!socket.isClosed())
  248                   socket.close();
  249           } else
  250               impl.close();
  251           closing = false;
  252       }
  253   
  254       void setEOF(boolean eof) {
  255           this.eof = eof;
  256       }
  257   
  258       /**
  259        * Overrides finalize, the fd is closed by the Socket.
  260        */
  261       protected void finalize() {}
  262   
  263       /**
  264        * Perform class load-time initializations.
  265        */
  266       private native static void init();
  267   }

Save This Page
Home » apache-harmony-6.0-src-r917296-snapshot » java » net » [javadoc | source]