1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package sun.nio.ch; 28 29 import java.io.*; 30 import java.nio.*; 31 import java.nio.channels.*; 32 33 34 /** 35 * This class is defined here rather than in java.nio.channels.Channels 36 * so that code can be shared with SocketAdaptor. 37 * 38 * @author Mike McCloskey 39 * @author Mark Reinhold 40 * @since 1.4 41 */ 42 43 public class ChannelInputStream 44 extends InputStream 45 { 46 47 // Android-changed: This code didn't make sense. In particular, the block channel is 48 // useless because we throw if the channel is non-blocking!. It would only make sense 49 // if it's called on a blocking channel (but we're asked to make it non-blocking before 50 // the read) we never do that, though. 51 // 52 // read(ReadableByteChannel,ByteBuffer, boolean block) read(ReadableByteChannel ch, ByteBuffer bb)53 public static int read(ReadableByteChannel ch, ByteBuffer bb) 54 throws IOException 55 { 56 if (ch instanceof SelectableChannel) { 57 SelectableChannel sc = (SelectableChannel)ch; 58 synchronized (sc.blockingLock()) { 59 boolean bm = sc.isBlocking(); 60 if (!bm) 61 throw new IllegalBlockingModeException(); 62 // Android-removed. 63 // if (bm != block) 64 // sc.configureBlocking(block); 65 int n = ch.read(bb); 66 // Android-removed. 67 // if (bm != block) 68 // sc.configureBlocking(bm); 69 return n; 70 } 71 } else { 72 return ch.read(bb); 73 } 74 } 75 76 protected final ReadableByteChannel ch; 77 private ByteBuffer bb = null; 78 private byte[] bs = null; // Invoker's previous array 79 private byte[] b1 = null; 80 ChannelInputStream(ReadableByteChannel ch)81 public ChannelInputStream(ReadableByteChannel ch) { 82 this.ch = ch; 83 } 84 read()85 public synchronized int read() throws IOException { 86 if (b1 == null) 87 b1 = new byte[1]; 88 int n = this.read(b1); 89 if (n == 1) 90 return b1[0] & 0xff; 91 return -1; 92 } 93 read(byte[] bs, int off, int len)94 public synchronized int read(byte[] bs, int off, int len) 95 throws IOException 96 { 97 if ((off < 0) || (off > bs.length) || (len < 0) || 98 ((off + len) > bs.length) || ((off + len) < 0)) { 99 throw new IndexOutOfBoundsException(); 100 } else if (len == 0) 101 return 0; 102 103 ByteBuffer bb = ((this.bs == bs) 104 ? this.bb 105 : ByteBuffer.wrap(bs)); 106 bb.limit(Math.min(off + len, bb.capacity())); 107 bb.position(off); 108 this.bb = bb; 109 this.bs = bs; 110 return read(bb); 111 } 112 read(ByteBuffer bb)113 protected int read(ByteBuffer bb) 114 throws IOException 115 { 116 return ChannelInputStream.read(ch, bb); 117 } 118 available()119 public int available() throws IOException { 120 // special case where the channel is to a file 121 if (ch instanceof SeekableByteChannel) { 122 SeekableByteChannel sbc = (SeekableByteChannel)ch; 123 long rem = Math.max(0, sbc.size() - sbc.position()); 124 return (rem > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)rem; 125 } 126 return 0; 127 } 128 close()129 public void close() throws IOException { 130 ch.close(); 131 } 132 133 } 134