ChannelInputStream.java revision 2c87ad3a45cecf9e344487cad1abfdebe79f2c7c
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
27package sun.nio.ch;
28
29import java.io.*;
30import java.nio.*;
31import java.nio.channels.*;
32import java.nio.channels.spi.*;
33
34
35/**
36 * This class is defined here rather than in java.nio.channels.Channels
37 * so that code can be shared with SocketAdaptor.
38 *
39 * @author Mike McCloskey
40 * @author Mark Reinhold
41 * @since 1.4
42 */
43
44public class ChannelInputStream
45    extends InputStream
46{
47
48    // Android-changed : This code didn't make sense. In particular, the block channel is
49    // useless because we throw if the channel is non-blocking!. It would only make sense
50    // if it's called on a blocking channel (but we're asked to make it non-blocking before
51    // the read) we never do that, though.
52    //
53    // read(ReadableByteChannel,ByteBuffer, boolean block)
54    public static int read(ReadableByteChannel ch, ByteBuffer bb)
55        throws IOException
56    {
57        if (ch instanceof SelectableChannel) {
58            SelectableChannel sc = (SelectableChannel)ch;
59            synchronized (sc.blockingLock()) {
60                boolean bm = sc.isBlocking();
61                if (!bm)
62                    throw new IllegalBlockingModeException();
63                // Android removed.
64                // if (bm != block)
65                //    sc.configureBlocking(block);
66                int n = ch.read(bb);
67                // Android removed.
68                // if (bm != block)
69                //     sc.configureBlocking(bm);
70                return n;
71            }
72        } else {
73            return ch.read(bb);
74        }
75    }
76
77    protected final ReadableByteChannel ch;
78    private ByteBuffer bb = null;
79    private byte[] bs = null;           // Invoker's previous array
80    private byte[] b1 = null;
81
82    public ChannelInputStream(ReadableByteChannel ch) {
83        this.ch = ch;
84    }
85
86    public synchronized int read() throws IOException {
87        if (b1 == null)
88            b1 = new byte[1];
89        int n = this.read(b1);
90        if (n == 1)
91            return b1[0] & 0xff;
92        return -1;
93    }
94
95    public synchronized int read(byte[] bs, int off, int len)
96        throws IOException
97    {
98        if ((off < 0) || (off > bs.length) || (len < 0) ||
99            ((off + len) > bs.length) || ((off + len) < 0)) {
100            throw new IndexOutOfBoundsException();
101        } else if (len == 0)
102            return 0;
103
104        ByteBuffer bb = ((this.bs == bs)
105                         ? this.bb
106                         : ByteBuffer.wrap(bs));
107        bb.limit(Math.min(off + len, bb.capacity()));
108        bb.position(off);
109        this.bb = bb;
110        this.bs = bs;
111        return read(bb);
112    }
113
114    protected int read(ByteBuffer bb)
115        throws IOException
116    {
117        return ChannelInputStream.read(ch, bb);
118    }
119
120    public int available() throws IOException {
121        // special case where the channel is to a file
122        if (ch instanceof SeekableByteChannel) {
123            SeekableByteChannel sbc = (SeekableByteChannel)ch;
124            long rem = Math.max(0, sbc.size() - sbc.position());
125            return (rem > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)rem;
126        }
127        return 0;
128    }
129
130    public void close() throws IOException {
131        ch.close();
132    }
133
134}
135