src/java.base/share/classes/sun/security/ssl/ByteBufferInputStream.java
changeset 50768 68fa3d4026ea
parent 50767 356eaea05bf0
child 50769 1bf8f9840705
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
     1 /*
       
     2  * Copyright (c) 2003, 2014, 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 sun.security.ssl;
       
    27 
       
    28 import java.io.*;
       
    29 import java.nio.*;
       
    30 
       
    31 /**
       
    32  * A simple InputStream which uses ByteBuffers as it's backing store.
       
    33  * <P>
       
    34  * The only IOException should come if the InputStream has been closed.
       
    35  * All other IOException should not occur because all the data is local.
       
    36  * Data reads on an exhausted ByteBuffer returns a -1.
       
    37  *
       
    38  * @author  Brad Wetmore
       
    39  */
       
    40 class ByteBufferInputStream extends InputStream {
       
    41 
       
    42     ByteBuffer bb;
       
    43 
       
    44     ByteBufferInputStream(ByteBuffer bb) {
       
    45         this.bb = bb;
       
    46     }
       
    47 
       
    48     /**
       
    49      * Returns a byte from the ByteBuffer.
       
    50      *
       
    51      * Increments position().
       
    52      */
       
    53     @Override
       
    54     public int read() throws IOException {
       
    55 
       
    56         if (bb == null) {
       
    57             throw new IOException("read on a closed InputStream");
       
    58         }
       
    59 
       
    60         if (bb.remaining() == 0) {
       
    61             return -1;
       
    62         }
       
    63 
       
    64         return (bb.get() & 0xFF);   // need to be in the range 0 to 255
       
    65     }
       
    66 
       
    67     /**
       
    68      * Returns a byte array from the ByteBuffer.
       
    69      *
       
    70      * Increments position().
       
    71      */
       
    72     @Override
       
    73     public int read(byte[] b) throws IOException {
       
    74 
       
    75         if (bb == null) {
       
    76             throw new IOException("read on a closed InputStream");
       
    77         }
       
    78 
       
    79         return read(b, 0, b.length);
       
    80     }
       
    81 
       
    82     /**
       
    83      * Returns a byte array from the ByteBuffer.
       
    84      *
       
    85      * Increments position().
       
    86      */
       
    87     @Override
       
    88     public int read(byte[] b, int off, int len) throws IOException {
       
    89 
       
    90         if (bb == null) {
       
    91             throw new IOException("read on a closed InputStream");
       
    92         }
       
    93 
       
    94         if (b == null) {
       
    95             throw new NullPointerException();
       
    96         } else if (off < 0 || len < 0 || len > b.length - off) {
       
    97             throw new IndexOutOfBoundsException();
       
    98         } else if (len == 0) {
       
    99             return 0;
       
   100         }
       
   101 
       
   102         int length = Math.min(bb.remaining(), len);
       
   103         if (length == 0) {
       
   104             return -1;
       
   105         }
       
   106 
       
   107         bb.get(b, off, length);
       
   108         return length;
       
   109     }
       
   110 
       
   111     /**
       
   112      * Skips over and discards <code>n</code> bytes of data from this input
       
   113      * stream.
       
   114      */
       
   115     @Override
       
   116     public long skip(long n) throws IOException {
       
   117 
       
   118         if (bb == null) {
       
   119             throw new IOException("skip on a closed InputStream");
       
   120         }
       
   121 
       
   122         if (n <= 0) {
       
   123             return 0;
       
   124         }
       
   125 
       
   126         /*
       
   127          * ByteBuffers have at most an int, so lose the upper bits.
       
   128          * The contract allows this.
       
   129          */
       
   130         int nInt = (int) n;
       
   131         int skip = Math.min(bb.remaining(), nInt);
       
   132 
       
   133         bb.position(bb.position() + skip);
       
   134 
       
   135         return nInt;
       
   136     }
       
   137 
       
   138     /**
       
   139      * Returns the number of bytes that can be read (or skipped over)
       
   140      * from this input stream without blocking by the next caller of a
       
   141      * method for this input stream.
       
   142      */
       
   143     @Override
       
   144     public int available() throws IOException {
       
   145 
       
   146         if (bb == null) {
       
   147             throw new IOException("available on a closed InputStream");
       
   148         }
       
   149 
       
   150         return bb.remaining();
       
   151     }
       
   152 
       
   153     /**
       
   154      * Closes this input stream and releases any system resources associated
       
   155      * with the stream.
       
   156      *
       
   157      * @exception  IOException  if an I/O error occurs.
       
   158      */
       
   159     @Override
       
   160     public void close() throws IOException {
       
   161         bb = null;
       
   162     }
       
   163 
       
   164     /**
       
   165      * Marks the current position in this input stream.
       
   166      */
       
   167     @Override
       
   168     public synchronized void mark(int readlimit) {}
       
   169 
       
   170     /**
       
   171      * Repositions this stream to the position at the time the
       
   172      * <code>mark</code> method was last called on this input stream.
       
   173      */
       
   174     @Override
       
   175     public synchronized void reset() throws IOException {
       
   176         throw new IOException("mark/reset not supported");
       
   177     }
       
   178 
       
   179     /**
       
   180      * Tests if this input stream supports the <code>mark</code> and
       
   181      * <code>reset</code> methods.
       
   182      */
       
   183     @Override
       
   184     public boolean markSupported() {
       
   185         return false;
       
   186     }
       
   187 }