@Override public boolean renameTo(File dest) throws IOException { if (dest == null) { throw new NullPointerException("dest"); } if (byteBuf == null) { // empty file dest.createNewFile(); isRenamed = true; return true; } int length = byteBuf.readableBytes(); FileOutputStream outputStream = new FileOutputStream(dest); FileChannel fileChannel = outputStream.getChannel(); int written = 0; if (byteBuf.nioBufferCount() == 1) { ByteBuffer byteBuffer = byteBuf.nioBuffer(); while (written < length) { written += fileChannel.write(byteBuffer); } } else { ByteBuffer[] byteBuffers = byteBuf.nioBuffers(); while (written < length) { written += fileChannel.write(byteBuffers); } } fileChannel.force(false); fileChannel.close(); outputStream.close(); isRenamed = true; return written == length; }
private SSLEngineResult unwrap( SSLEngine engine, ByteBuf in, int readerIndex, int len, ByteBuf out) throws SSLException { int nioBufferCount = in.nioBufferCount(); int writerIndex = out.writerIndex(); final SSLEngineResult result; if (engine instanceof OpenSslEngine && nioBufferCount > 1) { /** * If {@link OpenSslEngine} is in use, we can use a special {@link * OpenSslEngine#unwrap(ByteBuffer[], ByteBuffer[])} method that accepts multiple {@link * ByteBuffer}s without additional memory copies. */ OpenSslEngine opensslEngine = (OpenSslEngine) engine; try { singleBuffer[0] = toByteBuffer(out, writerIndex, out.writableBytes()); result = opensslEngine.unwrap(in.nioBuffers(readerIndex, len), singleBuffer); out.writerIndex(writerIndex + result.bytesProduced()); } finally { singleBuffer[0] = null; } } else { result = engine.unwrap( toByteBuffer(in, readerIndex, len), toByteBuffer(out, writerIndex, out.writableBytes())); } out.writerIndex(writerIndex + result.bytesProduced()); return result; }
@Override protected boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception { SctpMessage packet = (SctpMessage) msg; ByteBuf data = packet.content(); int dataLen = data.readableBytes(); if (dataLen == 0) { return true; } ByteBufAllocator alloc = alloc(); boolean needsCopy = data.nioBufferCount() != 1; if (!needsCopy) { if (!data.isDirect() && alloc.isDirectBufferPooled()) { needsCopy = true; } } ByteBuffer nioData; if (!needsCopy) { nioData = data.nioBuffer(); } else { data = alloc.directBuffer(dataLen).writeBytes(data); nioData = data.nioBuffer(); } final MessageInfo mi = MessageInfo.createOutgoing(association(), null, packet.streamIdentifier()); mi.payloadProtocolID(packet.protocolIdentifier()); mi.streamNumber(packet.streamIdentifier()); mi.unordered(packet.isUnordered()); final int writtenBytes = javaChannel().send(nioData, mi); return writtenBytes > 0; }
@Override protected int doWriteMessages(MessageBuf<Object> buf, boolean lastSpin) throws Exception { DatagramPacket packet = (DatagramPacket) buf.peek(); ByteBuf data = packet.data(); int dataLen = data.readableBytes(); ByteBuffer nioData; if (data.nioBufferCount() == 1) { nioData = data.nioBuffer(); } else { nioData = ByteBuffer.allocate(dataLen); data.getBytes(data.readerIndex(), nioData); nioData.flip(); } final int writtenBytes = javaChannel().send(nioData, packet.remoteAddress()); final SelectionKey key = selectionKey(); final int interestOps = key.interestOps(); if (writtenBytes <= 0 && dataLen > 0) { // Did not write a packet. // 1) If 'lastSpin' is false, the caller will call this method again real soon. // - Do not update OP_WRITE. // 2) If 'lastSpin' is true, the caller will not retry. // - Set OP_WRITE so that the event loop calls flushForcibly() later. if (lastSpin) { if ((interestOps & SelectionKey.OP_WRITE) == 0) { key.interestOps(interestOps | SelectionKey.OP_WRITE); } } return 0; } // Wrote a packet. buf.remove(); // packet was written free up buffer packet.free(); if (buf.isEmpty()) { // Wrote the outbound buffer completely - clear OP_WRITE. if ((interestOps & SelectionKey.OP_WRITE) != 0) { key.interestOps(interestOps & ~SelectionKey.OP_WRITE); } } return 1; }
@Override protected final Object filterOutboundMessage(Object msg) throws Exception { if (msg instanceof SctpMessage) { SctpMessage m = (SctpMessage) msg; ByteBuf buf = m.content(); if (buf.isDirect() && buf.nioBufferCount() == 1) { return m; } return new SctpMessage( m.protocolIdentifier(), m.streamIdentifier(), m.isUnordered(), newDirectBuffer(m, buf)); } throw new UnsupportedOperationException( "unsupported message type: " + StringUtil.simpleClassName(msg) + " (expected: " + StringUtil.simpleClassName(SctpMessage.class)); }
public ByteBuf getBytes(int var1, ByteBuf var2, int var3, int var4) { this.checkDstIndex(var1, var4, var3, var2.capacity()); if (var2.hasArray()) { this.getBytes(var1, var2.array(), var2.arrayOffset() + var3, var4); } else if (var2.nioBufferCount() > 0) { ByteBuffer[] var5 = var2.nioBuffers(var3, var4); int var6 = var5.length; for (int var7 = 0; var7 < var6; ++var7) { ByteBuffer var8 = var5[var7]; int var9 = var8.remaining(); this.getBytes(var1, var8); var1 += var9; } } else { var2.setBytes(var3, (ByteBuf) this, var1, var4); } return this; }
/** * 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; }
@Override protected boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception { final Object m; final SocketAddress remoteAddress; ByteBuf data; if (msg instanceof AddressedEnvelope) { @SuppressWarnings("unchecked") AddressedEnvelope<Object, SocketAddress> envelope = (AddressedEnvelope<Object, SocketAddress>) msg; remoteAddress = envelope.recipient(); m = envelope.content(); } else { m = msg; remoteAddress = null; } if (m instanceof ByteBufHolder) { data = ((ByteBufHolder) m).content(); } else if (m instanceof ByteBuf) { data = (ByteBuf) m; } else { throw new UnsupportedOperationException( "unsupported message type: " + StringUtil.simpleClassName(msg)); } int dataLen = data.readableBytes(); if (dataLen == 0) { return true; } ByteBufAllocator alloc = alloc(); boolean needsCopy = data.nioBufferCount() != 1; if (!needsCopy) { if (!data.isDirect() && alloc.isDirectBufferPooled()) { needsCopy = true; } } ByteBuffer nioData; if (!needsCopy) { nioData = data.nioBuffer(); } else { data = alloc.directBuffer(dataLen).writeBytes(data); nioData = data.nioBuffer(); } final int writtenBytes; if (remoteAddress != null) { writtenBytes = javaChannel().send(nioData, remoteAddress); } else { writtenBytes = javaChannel().write(nioData); } boolean done = writtenBytes > 0; if (needsCopy) { // This means we have allocated a new buffer and need to store it back so we not need to // allocate it again // later if (remoteAddress == null) { // remoteAddress is null which means we can handle it as ByteBuf directly in.current(data); } else { if (!done) { // store it back with all the needed informations in.current(new DefaultAddressedEnvelope<ByteBuf, SocketAddress>(data, remoteAddress)); } else { // Just store back the new create buffer so it is cleaned up once in.remove() is called. in.current(data); } } } return done; }
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 int nioBufferCount() { return buf.nioBufferCount(); }
/** * Checks if the specified buffer is a direct buffer and is composed of a single NIO buffer. (We * check this because otherwise we need to make it a non-composite buffer.) */ private static boolean isSingleDirectBuffer(ByteBuf buf) { return buf.isDirect() && buf.nioBufferCount() == 1; }