static void toHexString(String header, ByteBuffer buf) { sb.delete(0, sb.length()); for (int index = 0; index < buf.limit(); index++) { String hex = Integer.toHexString(0x0100 + (buf.get(index) & 0x00FF)).substring(1); sb.append((hex.length() < 2 ? "0" : "") + hex + " "); } LOG.debug( "hex->" + header + ": position,limit,capacity " + buf.position() + "," + buf.limit() + "," + buf.capacity()); LOG.debug("hex->" + sb.toString()); }
public static void main(String args[]) throws Exception { ByteBuffer buffer = ByteBuffer.allocate(10); for (int i = 0; i < buffer.capacity(); ++i) { buffer.put((byte) i); } buffer.position(3); buffer.limit(7); ByteBuffer slice = buffer.slice(); for (int i = 0; i < slice.capacity(); ++i) { byte b = slice.get(i); b *= 11; slice.put(i, b); } buffer.position(0); buffer.limit(buffer.capacity()); while (buffer.hasRemaining()) { System.out.println(buffer.get()); } }
/** * Gets the <i>i</i>th mipmap data (0..getNumMipMaps() - 1) * * @param side Cubemap side or 0 for 2D texture * @param map Mipmap index * @return Image object */ public ImageInfo getMipMap(int side, int map) { if (!isCubemap() && (side != 0)) { throw new RuntimeException("Illegal side for 2D texture: " + side); } if (isCubemap() && !isCubemapSidePresent(side)) { throw new RuntimeException("Illegal side, side not present: " + side); } if (getNumMipMaps() > 0 && ((map < 0) || (map >= getNumMipMaps()))) { throw new RuntimeException( "Illegal mipmap number " + map + " (0.." + (getNumMipMaps() - 1) + ")"); } // Figure out how far to seek int seek = Header.writtenSize(); if (isCubemap()) { seek += sideShiftInBytes(side); } for (int i = 0; i < map; i++) { seek += mipMapSizeInBytes(i); } buf.limit(seek + mipMapSizeInBytes(map)); buf.position(seek); ByteBuffer next = buf.slice(); buf.position(0); buf.limit(buf.capacity()); return new ImageInfo( next, mipMapWidth(map), mipMapHeight(map), isCompressed(), getCompressionFormat()); }
/* * Return a ByteBuffer with "remaining" space to work. If you have to * reallocate the ByteBuffer, copy the existing info into the new buffer. */ protected void resizeRequestBB(int remaining) { if (requestBB.remaining() < remaining) { // Expand buffer for large request ByteBuffer bb = ByteBuffer.allocate(requestBB.capacity() * 2); requestBB.flip(); bb.put(requestBB); requestBB = bb; } }
static void printBBInfo(ByteBuffer buf) { LOG.debug( "Info : position,limit,capacity " + buf.position() + "," + buf.limit() + "," + buf.capacity()); }
/* * Read the channel for more information, then unwrap the * (hopefully application) data we get. * <P> * If we run out of data, we'll return to our caller (possibly using * a Selector) to get notification that more is available. * <P> * Each call to this method will perform at most one underlying read(). */ int read() throws IOException { SSLEngineResult result; if (!initialHSComplete) { throw new IllegalStateException(); } int pos = requestBB.position(); if (sc.read(inNetBB) == -1) { sslEngine.closeInbound(); // probably throws exception return -1; } do { resizeRequestBB(); // expected room for unwrap inNetBB.flip(); result = sslEngine.unwrap(inNetBB, requestBB); inNetBB.compact(); /* * Could check here for a renegotation, but we're only * doing a simple read/write, and won't have enough state * transitions to do a complete handshake, so ignore that * possibility. */ switch (result.getStatus()) { case BUFFER_OVERFLOW: // Reset the application buffer size. appBBSize = sslEngine.getSession().getApplicationBufferSize(); break; case BUFFER_UNDERFLOW: // Resize buffer if needed. netBBSize = sslEngine.getSession().getPacketBufferSize(); if (netBBSize > inNetBB.capacity()) { resizeResponseBB(); break; // break, next read will support larger buffer. } case OK: if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { doTasks(); } break; default: throw new IOException("sslEngine error during data read: " + result.getStatus()); } } while ((inNetBB.position() != 0) && result.getStatus() != Status.BUFFER_UNDERFLOW); return (requestBB.position() - pos); }
private synchronized DBMessage go(DBMessage msg, ByteDecoder decoder) throws IOException { if (_sock == null) _open(); { ByteBuffer out = msg.prepare(); while (out.remaining() > 0) _sock.write(out); } if (_pool != null) _pool._everWorked = true; if (decoder == null) return null; ByteBuffer response = decoder._buf; if (response.position() != 0) throw new IllegalArgumentException(); int read = 0; while (read < DBMessage.HEADER_LENGTH) read += _read(response); int len = response.getInt(0); if (len <= DBMessage.HEADER_LENGTH) throw new IllegalArgumentException("db sent invalid length: " + len); if (len > response.capacity()) throw new IllegalArgumentException( "db message size is too big (" + len + ") " + "max is (" + response.capacity() + ")"); response.limit(len); while (read < len) read += _read(response); if (read != len) throw new RuntimeException("something is wrong"); response.flip(); return new DBMessage(response); }
/* * Perform any handshaking processing. * <P> * If a SelectionKey is passed, register for selectable * operations. * <P> * In the blocking case, our caller will keep calling us until * we finish the handshake. Our reads/writes will block as expected. * <P> * In the non-blocking case, we just received the selection notification * that this channel is ready for whatever the operation is, so give * it a try. * <P> * return: * true when handshake is done. * false while handshake is in progress */ boolean doHandshake(SelectionKey sk) throws IOException { SSLEngineResult result; if (initialHSComplete) { return initialHSComplete; } /* * Flush out the outgoing buffer, if there's anything left in * it. */ if (outNetBB.hasRemaining()) { if (!tryFlush(outNetBB)) { return false; } // See if we need to switch from write to read mode. switch (initialHSStatus) { /* * Is this the last buffer? */ case FINISHED: initialHSComplete = true; // Fall-through to reregister need for a Read. case NEED_UNWRAP: if (sk != null) { sk.interestOps(SelectionKey.OP_READ); } break; } return initialHSComplete; } switch (initialHSStatus) { case NEED_UNWRAP: if (sc.read(inNetBB) == -1) { sslEngine.closeInbound(); return initialHSComplete; } needIO: while (initialHSStatus == HandshakeStatus.NEED_UNWRAP) { resizeRequestBB(); // expected room for unwrap inNetBB.flip(); result = sslEngine.unwrap(inNetBB, requestBB); inNetBB.compact(); initialHSStatus = result.getHandshakeStatus(); switch (result.getStatus()) { case OK: switch (initialHSStatus) { case NOT_HANDSHAKING: throw new IOException("Not handshaking during initial handshake"); case NEED_TASK: initialHSStatus = doTasks(); break; case FINISHED: initialHSComplete = true; break needIO; } break; case BUFFER_UNDERFLOW: // Resize buffer if needed. netBBSize = sslEngine.getSession().getPacketBufferSize(); if (netBBSize > inNetBB.capacity()) { resizeResponseBB(); } /* * Need to go reread the Channel for more data. */ if (sk != null) { sk.interestOps(SelectionKey.OP_READ); } break needIO; case BUFFER_OVERFLOW: // Reset the application buffer size. appBBSize = sslEngine.getSession().getApplicationBufferSize(); break; default: // CLOSED: throw new IOException("Received" + result.getStatus() + "during initial handshaking"); } } // "needIO" block. /* * Just transitioned from read to write. */ if (initialHSStatus != HandshakeStatus.NEED_WRAP) { break; } // Fall through and fill the write buffers. case NEED_WRAP: /* * The flush above guarantees the out buffer to be empty */ outNetBB.clear(); result = sslEngine.wrap(hsBB, outNetBB); outNetBB.flip(); initialHSStatus = result.getHandshakeStatus(); switch (result.getStatus()) { case OK: if (initialHSStatus == HandshakeStatus.NEED_TASK) { initialHSStatus = doTasks(); } if (sk != null) { sk.interestOps(SelectionKey.OP_WRITE); } break; default: // BUFFER_OVERFLOW/BUFFER_UNDERFLOW/CLOSED: throw new IOException("Received" + result.getStatus() + "during initial handshaking"); } break; default: // NOT_HANDSHAKING/NEED_TASK/FINISHED throw new RuntimeException("Invalid Handshaking State" + initialHSStatus); } // switch return initialHSComplete; }
private void readMessage(SelectionKey sk, SocketChannel readChannel, TcpAddress incomingAddress) throws IOException { // note that socket has been used SocketEntry entry = (SocketEntry) sockets.get(incomingAddress); if (entry != null) { entry.used(); ByteBuffer readBuffer = entry.getReadBuffer(); if (readBuffer != null) { readChannel.read(readBuffer); if (readBuffer.hasRemaining()) { readChannel.register(selector, SelectionKey.OP_READ, entry); } else { dispatchMessage(incomingAddress, readBuffer, readBuffer.capacity()); } return; } } ByteBuffer byteBuffer = ByteBuffer.wrap(buf); byteBuffer.limit(messageLengthDecoder.getMinHeaderLength()); long bytesRead = readChannel.read(byteBuffer); if (logger.isDebugEnabled()) { logger.debug("Reading header " + bytesRead + " bytes from " + incomingAddress); } MessageLength messageLength = new MessageLength(0, Integer.MIN_VALUE); if (bytesRead == messageLengthDecoder.getMinHeaderLength()) { messageLength = messageLengthDecoder.getMessageLength(ByteBuffer.wrap(buf)); if (logger.isDebugEnabled()) { logger.debug("Message length is " + messageLength); } if ((messageLength.getMessageLength() > getMaxInboundMessageSize()) || (messageLength.getMessageLength() <= 0)) { logger.error( "Received message length " + messageLength + " is greater than inboundBufferSize " + getMaxInboundMessageSize()); synchronized (entry) { entry.getSocket().close(); logger.info("Socket to " + entry.getPeerAddress() + " closed due to an error"); } } else { byteBuffer.limit(messageLength.getMessageLength()); bytesRead += readChannel.read(byteBuffer); if (bytesRead == messageLength.getMessageLength()) { dispatchMessage(incomingAddress, byteBuffer, bytesRead); } else { byte[] message = new byte[byteBuffer.limit()]; byteBuffer.flip(); byteBuffer.get(message, 0, byteBuffer.limit() - byteBuffer.remaining()); entry.setReadBuffer(ByteBuffer.wrap(message)); } readChannel.register(selector, SelectionKey.OP_READ, entry); } } else if (bytesRead < 0) { logger.debug("Socket closed remotely"); sk.cancel(); readChannel.close(); TransportStateEvent e = new TransportStateEvent( DefaultTcpTransportMapping.this, incomingAddress, TransportStateEvent.STATE_DISCONNECTED_REMOTELY, null); fireConnectionStateChanged(e); } }