@Override protected int doReadMessages(List<Object> buf) throws Exception { DatagramChannel ch = javaChannel(); DatagramChannelConfig config = config(); RecvByteBufAllocator.Handle allocHandle = this.allocHandle; if (allocHandle == null) { this.allocHandle = allocHandle = config.getRecvByteBufAllocator().newHandle(); } ByteBuf data = allocHandle.allocate(config.getAllocator()); boolean free = true; try { ByteBuffer nioData = data.internalNioBuffer(data.writerIndex(), data.writableBytes()); int pos = nioData.position(); InetSocketAddress remoteAddress = (InetSocketAddress) ch.receive(nioData); if (remoteAddress == null) { return 0; } int readBytes = nioData.position() - pos; data.writerIndex(data.writerIndex() + readBytes); allocHandle.record(readBytes); buf.add(new DatagramPacket(data, localAddress(), remoteAddress)); free = false; return 1; } catch (Throwable cause) { PlatformDependent.throwException(cause); return -1; } finally { if (free) { data.release(); } } }
@Override protected int doReadMessages(List<Object> buf) throws Exception { SctpChannel ch = javaChannel(); RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle(); ByteBuf buffer = allocHandle.allocate(config().getAllocator()); boolean free = true; try { ByteBuffer data = buffer.internalNioBuffer(buffer.writerIndex(), buffer.writableBytes()); int pos = data.position(); MessageInfo messageInfo = ch.receive(data, null, notificationHandler); if (messageInfo == null) { return 0; } buf.add( new SctpMessage( messageInfo, buffer.writerIndex(buffer.writerIndex() + data.position() - pos))); free = false; return 1; } catch (Throwable cause) { PlatformDependent.throwException(cause); return -1; } finally { int bytesRead = buffer.readableBytes(); allocHandle.record(bytesRead); if (free) { buffer.release(); } } }
@Override protected boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception { final SocketAddress remoteAddress; final ByteBuf data; if (msg instanceof AddressedEnvelope) { @SuppressWarnings("unchecked") AddressedEnvelope<ByteBuf, SocketAddress> envelope = (AddressedEnvelope<ByteBuf, SocketAddress>) msg; remoteAddress = envelope.recipient(); data = envelope.content(); } else { data = (ByteBuf) msg; remoteAddress = null; } final int dataLen = data.readableBytes(); if (dataLen == 0) { return true; } final ByteBuffer nioData = data.internalNioBuffer(data.readerIndex(), dataLen); final int writtenBytes; if (remoteAddress != null) { writtenBytes = javaChannel().send(nioData, remoteAddress); } else { writtenBytes = javaChannel().write(nioData); } return writtenBytes > 0; }
/** Read bytes into the given {@link ByteBuf} and return the amount. */ private int doReadBytes(ByteBuf byteBuf) throws Exception { int writerIndex = byteBuf.writerIndex(); int localReadAmount; if (byteBuf.hasMemoryAddress()) { localReadAmount = Native.readAddress(fd, byteBuf.memoryAddress(), writerIndex, byteBuf.capacity()); } else { ByteBuffer buf = byteBuf.internalNioBuffer(writerIndex, byteBuf.writableBytes()); localReadAmount = Native.read(fd, buf, buf.position(), buf.limit()); } if (localReadAmount > 0) { byteBuf.writerIndex(writerIndex + localReadAmount); } return localReadAmount; }
/** * Write bytes form the given {@link ByteBuf} to the underlying {@link java.nio.channels.Channel}. * * @param buf the {@link ByteBuf} from which the bytes should be written * @return amount the amount of written bytes */ private int doWriteBytes(ByteBuf buf, int readable) throws Exception { int readerIndex = buf.readerIndex(); int localFlushedAmount; if (buf.nioBufferCount() == 1) { if (buf.hasMemoryAddress()) { localFlushedAmount = Native.writeAddress(fd, buf.memoryAddress(), readerIndex, buf.writerIndex()); } else { ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readable); localFlushedAmount = Native.write(fd, nioBuf, nioBuf.position(), nioBuf.limit()); } } else { // backed by more then one buffer, do a gathering write... ByteBuffer[] nioBufs = buf.nioBuffers(); localFlushedAmount = (int) Native.writev(fd, nioBufs, 0, nioBufs.length); } if (localFlushedAmount > 0) { buf.readerIndex(readerIndex + localFlushedAmount); } return localFlushedAmount; }
private SSLEngineResult wrap(ByteBufAllocator alloc, SSLEngine engine, ByteBuf in, ByteBuf out) throws SSLException { ByteBuf newDirectIn = null; try { int readerIndex = in.readerIndex(); int readableBytes = in.readableBytes(); // We will call SslEngine.wrap(ByteBuffer[], ByteBuffer) to allow efficient handling of // CompositeByteBuf without force an extra memory copy when CompositeByteBuffer.nioBuffer() is // called. final ByteBuffer[] in0; if (in.isDirect() || !wantsDirectBuffer) { // As CompositeByteBuf.nioBufferCount() can be expensive (as it needs to check all composed // ByteBuf // to calculate the count) we will just assume a CompositeByteBuf contains more then 1 // ByteBuf. // The worst that can happen is that we allocate an extra ByteBuffer[] in // CompositeByteBuf.nioBuffers() // which is better then walking the composed ByteBuf in most cases. if (!(in instanceof CompositeByteBuf) && in.nioBufferCount() == 1) { in0 = singleBuffer; // We know its only backed by 1 ByteBuffer so use internalNioBuffer to keep object // allocation // to a minimum. in0[0] = in.internalNioBuffer(readerIndex, readableBytes); } else { in0 = in.nioBuffers(); } } else { // We could even go further here and check if its a CompositeByteBuf and if so try to // decompose it and // only replace the ByteBuffer that are not direct. At the moment we just will replace the // whole // CompositeByteBuf to keep the complexity to a minimum newDirectIn = alloc.directBuffer(readableBytes); newDirectIn.writeBytes(in, readerIndex, readableBytes); in0 = singleBuffer; in0[0] = newDirectIn.internalNioBuffer(0, readableBytes); } for (; ; ) { ByteBuffer out0 = out.nioBuffer(out.writerIndex(), out.writableBytes()); SSLEngineResult result = engine.wrap(in0, out0); in.skipBytes(result.bytesConsumed()); out.writerIndex(out.writerIndex() + result.bytesProduced()); switch (result.getStatus()) { case BUFFER_OVERFLOW: out.ensureWritable(maxPacketBufferSize); break; default: return result; } } } finally { // Null out to allow GC of ByteBuffer singleBuffer[0] = null; if (newDirectIn != null) { newDirectIn.release(); } } }
private static ByteBuffer toByteBuffer(ByteBuf out, int index, int len) { return out.nioBufferCount() == 1 ? out.internalNioBuffer(index, len) : out.nioBuffer(index, len); }
@Override public ByteBuffer internalNioBuffer(int var1, int var2) { return a.internalNioBuffer(var1, var2); }