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