1/* 2 * Copyright (c) 2003, 2009, 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 26package sun.security.ssl; 27 28import java.io.*; 29import 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 */ 40class 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 public int read() throws IOException { 54 55 if (bb == null) { 56 throw new IOException("read on a closed InputStream"); 57 } 58 59 if (bb.remaining() == 0) { 60 return -1; 61 } 62 return bb.get(); 63 } 64 65 /** 66 * Returns a byte array from the ByteBuffer. 67 * 68 * Increments position(). 69 */ 70 public int read(byte b[]) throws IOException { 71 72 if (bb == null) { 73 throw new IOException("read on a closed InputStream"); 74 } 75 76 return read(b, 0, b.length); 77 } 78 79 /** 80 * Returns a byte array from the ByteBuffer. 81 * 82 * Increments position(). 83 */ 84 public int read(byte b[], int off, int len) throws IOException { 85 86 if (bb == null) { 87 throw new IOException("read on a closed InputStream"); 88 } 89 90 if (b == null) { 91 throw new NullPointerException(); 92 } else if (off < 0 || len < 0 || len > b.length - off) { 93 throw new IndexOutOfBoundsException(); 94 } else if (len == 0) { 95 return 0; 96 } 97 98 int length = Math.min(bb.remaining(), len); 99 if (length == 0) { 100 return -1; 101 } 102 103 bb.get(b, off, length); 104 return length; 105 } 106 107 /** 108 * Skips over and discards <code>n</code> bytes of data from this input 109 * stream. 110 */ 111 public long skip(long n) throws IOException { 112 113 if (bb == null) { 114 throw new IOException("skip on a closed InputStream"); 115 } 116 117 if (n <= 0) { 118 return 0; 119 } 120 121 /* 122 * ByteBuffers have at most an int, so lose the upper bits. 123 * The contract allows this. 124 */ 125 int nInt = (int) n; 126 int skip = Math.min(bb.remaining(), nInt); 127 128 bb.position(bb.position() + skip); 129 130 return nInt; 131 } 132 133 /** 134 * Returns the number of bytes that can be read (or skipped over) 135 * from this input stream without blocking by the next caller of a 136 * method for this input stream. 137 */ 138 public int available() throws IOException { 139 140 if (bb == null) { 141 throw new IOException("available on a closed InputStream"); 142 } 143 144 return bb.remaining(); 145 } 146 147 /** 148 * Closes this input stream and releases any system resources associated 149 * with the stream. 150 * 151 * @exception IOException if an I/O error occurs. 152 */ 153 public void close() throws IOException { 154 bb = null; 155 } 156 157 /** 158 * Marks the current position in this input stream. 159 */ 160 public synchronized void mark(int readlimit) {} 161 162 /** 163 * Repositions this stream to the position at the time the 164 * <code>mark</code> method was last called on this input stream. 165 */ 166 public synchronized void reset() throws IOException { 167 throw new IOException("mark/reset not supported"); 168 } 169 170 /** 171 * Tests if this input stream supports the <code>mark</code> and 172 * <code>reset</code> methods. 173 */ 174 public boolean markSupported() { 175 return false; 176 } 177} 178