• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  *   - Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  *
11  *   - Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *   - Neither the name of Oracle nor the names of its
16  *     contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * This source code is provided to illustrate the usage of a given feature
34  * or technique and has been deliberately simplified. Additional steps
35  * required for a production-quality application, such as security checks,
36  * input validation and proper error handling, might not be present in
37  * this sample code.
38  */
39 
40 
41 import java.io.*;
42 import java.nio.*;
43 import java.nio.channels.*;
44 
45 /**
46  * A helper class for properly sizing inbound byte buffers and
47  * redirecting I/O calls to the proper SocketChannel call.
48  * <P>
49  * Many of these calls may seem unnecessary until you consider
50  * that they are placeholders for the secure variant, which is much
51  * more involved.  See ChannelIOSecure for more information.
52  *
53  * @author Brad R. Wetmore
54  * @author Mark Reinhold
55  */
56 class ChannelIO {
57 
58     protected SocketChannel sc;
59 
60     /*
61      * All of the inbound request data lives here until we determine
62      * that we've read everything, then we pass that data back to the
63      * caller.
64      */
65     protected ByteBuffer requestBB;
66     static private int requestBBSize = 4096;
67 
ChannelIO(SocketChannel sc, boolean blocking)68     protected ChannelIO(SocketChannel sc, boolean blocking)
69             throws IOException {
70         this.sc = sc;
71         sc.configureBlocking(blocking);
72     }
73 
getInstance(SocketChannel sc, boolean blocking)74     static ChannelIO getInstance(SocketChannel sc, boolean blocking)
75             throws IOException {
76         ChannelIO cio = new ChannelIO(sc, blocking);
77         cio.requestBB = ByteBuffer.allocate(requestBBSize);
78 
79         return cio;
80     }
81 
getSocketChannel()82     SocketChannel getSocketChannel() {
83         return sc;
84     }
85 
86     /*
87      * Return a ByteBuffer with "remaining" space to work.  If you have to
88      * reallocate the ByteBuffer, copy the existing info into the new buffer.
89      */
resizeRequestBB(int remaining)90     protected void resizeRequestBB(int remaining) {
91         if (requestBB.remaining() < remaining) {
92             // Expand buffer for large request
93             ByteBuffer bb = ByteBuffer.allocate(requestBB.capacity() * 2);
94             requestBB.flip();
95             bb.put(requestBB);
96             requestBB = bb;
97         }
98     }
99 
100     /*
101      * Perform any handshaking processing.
102      * <P>
103      * This variant is for Servers without SelectionKeys (e.g.
104      * blocking).
105      * <P>
106      * return true when we're done with handshaking.
107      */
doHandshake()108     boolean doHandshake() throws IOException {
109         return true;
110     }
111 
112     /*
113      * Perform any handshaking processing.
114      * <P>
115      * This variant is for Servers with SelectionKeys, so that
116      * we can register for selectable operations (e.g. selectable
117      * non-blocking).
118      * <P>
119      * return true when we're done with handshaking.
120      */
doHandshake(SelectionKey sk)121     boolean doHandshake(SelectionKey sk) throws IOException {
122         return true;
123     }
124 
125     /*
126      * Resize (if necessary) the inbound data buffer, and then read more
127      * data into the read buffer.
128      */
read()129     int read() throws IOException {
130         /*
131          * Allocate more space if less than 5% remains
132          */
133         resizeRequestBB(requestBBSize/20);
134         return sc.read(requestBB);
135     }
136 
137     /*
138      * All data has been read, pass back the request in one buffer.
139      */
getReadBuf()140     ByteBuffer getReadBuf() {
141         return requestBB;
142     }
143 
144     /*
145      * Write the src buffer into the socket channel.
146      */
write(ByteBuffer src)147     int write(ByteBuffer src) throws IOException {
148         return sc.write(src);
149     }
150 
151     /*
152      * Perform a FileChannel.TransferTo on the socket channel.
153      */
transferTo(FileChannel fc, long pos, long len)154     long transferTo(FileChannel fc, long pos, long len) throws IOException {
155         return fc.transferTo(pos, len, sc);
156     }
157 
158     /*
159      * Flush any outstanding data to the network if possible.
160      * <P>
161      * This isn't really necessary for the insecure variant, but needed
162      * for the secure one where intermediate buffering must take place.
163      * <P>
164      * Return true if successful.
165      */
dataFlush()166     boolean dataFlush() throws IOException {
167         return true;
168     }
169 
170     /*
171      * Start any connection shutdown processing.
172      * <P>
173      * This isn't really necessary for the insecure variant, but needed
174      * for the secure one where intermediate buffering must take place.
175      * <P>
176      * Return true if successful, and the data has been flushed.
177      */
shutdown()178     boolean shutdown() throws IOException {
179         return true;
180     }
181 
182     /*
183      * Close the underlying connection.
184      */
close()185     void close() throws IOException {
186         sc.close();
187     }
188 
189 }
190