src/share/classes/java/net/SocketOutputStream.java
author ohair
Tue May 25 15:58:33 2010 -0700 (24 months ago)
changeset 2361 00cd9dc3c2b5
parent 037a05a11f281
permissions -rw-r--r--
6943119: Rebrand source copyright notices
Reviewed-by: darcy, weijun
        1 /*
        2  * Copyright (c) 1995, 2007, Oracle and/or its affiliates. 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.  Oracle designates this
        8  * particular file as subject to the "Classpath" exception as provided
        9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       22  * or visit www.oracle.com if you need additional information or have any
       23  * questions.
       24  */
       25 
       26 package java.net;
       27 
       28 import java.io.FileDescriptor;
       29 import java.io.FileOutputStream;
       30 import java.io.IOException;
       31 import java.nio.channels.FileChannel;
       32 
       33 /**
       34  * This stream extends FileOutputStream to implement a
       35  * SocketOutputStream. Note that this class should <b>NOT</b> be
       36  * public.
       37  *
       38  * @author      Jonathan Payne
       39  * @author      Arthur van Hoff
       40  */
       41 class SocketOutputStream extends FileOutputStream
       42 {
       43     static {
       44         init();
       45     }
       46 
       47     private AbstractPlainSocketImpl impl = null;
       48     private byte temp[] = new byte[1];
       49     private Socket socket = null;
       50 
       51     /**
       52      * Creates a new SocketOutputStream. Can only be called
       53      * by a Socket. This method needs to hang on to the owner Socket so
       54      * that the fd will not be closed.
       55      * @param impl the socket output stream inplemented
       56      */
       57     SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
       58         super(impl.getFileDescriptor());
       59         this.impl = impl;
       60         socket = impl.getSocket();
       61     }
       62 
       63     /**
       64      * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
       65      * object associated with this file output stream. </p>
       66      *
       67      * The <code>getChannel</code> method of <code>SocketOutputStream</code>
       68      * returns <code>null</code> since it is a socket based stream.</p>
       69      *
       70      * @return  the file channel associated with this file output stream
       71      *
       72      * @since 1.4
       73      * @spec JSR-51
       74      */
       75     public final FileChannel getChannel() {
       76         return null;
       77     }
       78 
       79     /**
       80      * Writes to the socket.
       81      * @param fd the FileDescriptor
       82      * @param b the data to be written
       83      * @param off the start offset in the data
       84      * @param len the number of bytes that are written
       85      * @exception IOException If an I/O error has occurred.
       86      */
       87     private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
       88                                      int len) throws IOException;
       89 
       90     /**
       91      * Writes to the socket with appropriate locking of the
       92      * FileDescriptor.
       93      * @param b the data to be written
       94      * @param off the start offset in the data
       95      * @param len the number of bytes that are written
       96      * @exception IOException If an I/O error has occurred.
       97      */
       98     private void socketWrite(byte b[], int off, int len) throws IOException {
       99 
      100         if (len <= 0 || off < 0 || off + len > b.length) {
      101             if (len == 0) {
      102                 return;
      103             }
      104             throw new ArrayIndexOutOfBoundsException();
      105         }
      106 
      107         FileDescriptor fd = impl.acquireFD();
      108         try {
      109             socketWrite0(fd, b, off, len);
      110         } catch (SocketException se) {
      111             if (se instanceof sun.net.ConnectionResetException) {
      112                 impl.setConnectionResetPending();
      113                 se = new SocketException("Connection reset");
      114             }
      115             if (impl.isClosedOrPending()) {
      116                 throw new SocketException("Socket closed");
      117             } else {
      118                 throw se;
      119             }
      120         } finally {
      121             impl.releaseFD();
      122         }
      123     }
      124 
      125     /**
      126      * Writes a byte to the socket.
      127      * @param b the data to be written
      128      * @exception IOException If an I/O error has occurred.
      129      */
      130     public void write(int b) throws IOException {
      131         temp[0] = (byte)b;
      132         socketWrite(temp, 0, 1);
      133     }
      134 
      135     /**
      136      * Writes the contents of the buffer <i>b</i> to the socket.
      137      * @param b the data to be written
      138      * @exception SocketException If an I/O error has occurred.
      139      */
      140     public void write(byte b[]) throws IOException {
      141         socketWrite(b, 0, b.length);
      142     }
      143 
      144     /**
      145      * Writes <i>length</i> bytes from buffer <i>b</i> starting at
      146      * offset <i>len</i>.
      147      * @param b the data to be written
      148      * @param off the start offset in the data
      149      * @param len the number of bytes that are written
      150      * @exception SocketException If an I/O error has occurred.
      151      */
      152     public void write(byte b[], int off, int len) throws IOException {
      153         socketWrite(b, off, len);
      154     }
      155 
      156     /**
      157      * Closes the stream.
      158      */
      159     private boolean closing = false;
      160     public void close() throws IOException {
      161         // Prevent recursion. See BugId 4484411
      162         if (closing)
      163             return;
      164         closing = true;
      165         if (socket != null) {
      166             if (!socket.isClosed())
      167                 socket.close();
      168         } else
      169             impl.close();
      170         closing = false;
      171     }
      172 
      173     /**
      174      * Overrides finalize, the fd is closed by the Socket.
      175      */
      176     protected void finalize() {}
      177 
      178     /**
      179      * Perform class load-time initializations.
      180      */
      181     private native static void init();
      182 
      183 }