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 68 protected ChannelIO(SocketChannel sc, boolean blocking) 69 throws IOException { 70 this.sc = sc; 71 sc.configureBlocking(blocking); 72 } 73 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 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 */ 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 */ 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 */ 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 */ 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 */ 140 ByteBuffer getReadBuf() { 141 return requestBB; 142 } 143 144 /* 145 * Write the src buffer into the socket channel. 146 */ 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 */ 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 */ 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 */ 178 boolean shutdown() throws IOException { 179 return true; 180 } 181 182 /* 183 * Close the underlying connection. 184 */ 185 void close() throws IOException { 186 sc.close(); 187 } 188 189 } 190