Java Code Examples for io.netty.buffer.ByteBuf#writableBytes()

The following examples show how to use io.netty.buffer.ByteBuf#writableBytes() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AltsChannelCrypter.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Override
public void encrypt(ByteBuf outBuf, List<ByteBuf> plainBufs) throws GeneralSecurityException {
  byte[] tempArr = new byte[outBuf.writableBytes()];

  // Copy plaintext into tempArr.
  {
    ByteBuf tempBuf = Unpooled.wrappedBuffer(tempArr, 0, tempArr.length - TAG_LENGTH);
    tempBuf.resetWriterIndex();
    for (ByteBuf plainBuf : plainBufs) {
      tempBuf.writeBytes(plainBuf);
    }
  }

  // Encrypt into tempArr.
  {
    ByteBuffer out = ByteBuffer.wrap(tempArr);
    ByteBuffer plain = ByteBuffer.wrap(tempArr, 0, tempArr.length - TAG_LENGTH);

    byte[] counter = incrementOutCounter();
    aeadCrypter.encrypt(out, plain, counter);
  }
  outBuf.writeBytes(tempArr);
}
 
Example 2
Source File: AltsChannelCrypter.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Override
public void decrypt(ByteBuf outBuf, ByteBuf tagBuf, List<ByteBuf> ciphertextBufs)
    throws GeneralSecurityException {
  // There is enough space for the ciphertext including the tag in outBuf.
  byte[] tempArr = new byte[outBuf.writableBytes()];

  // Copy ciphertext and tag into tempArr.
  {
    ByteBuf tempBuf = Unpooled.wrappedBuffer(tempArr);
    tempBuf.resetWriterIndex();
    for (ByteBuf ciphertextBuf : ciphertextBufs) {
      tempBuf.writeBytes(ciphertextBuf);
    }
    tempBuf.writeBytes(tagBuf);
  }

  decryptInternal(outBuf, tempArr);
}
 
Example 3
Source File: SpdyHeaderBlockZlibEncoder.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
private boolean compressInto(ByteBuf compressed) {
    byte[] out = compressed.array();
    int off = compressed.arrayOffset() + compressed.writerIndex();
    int toWrite = compressed.writableBytes();
    int numBytes = compressor.deflate(out, off, toWrite, Deflater.SYNC_FLUSH);
    compressed.writerIndex(compressed.writerIndex() + numBytes);
    return numBytes == toWrite;
}
 
Example 4
Source File: StreamBufferingEncoderTest.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
private static ByteBuf data() {
    ByteBuf buf = Unpooled.buffer(10);
    for (int i = 0; i < buf.writableBytes(); i++) {
        buf.writeByte(i);
    }
    return buf;
}
 
Example 5
Source File: ByteBufUtils.java    From distributedlog with Apache License 2.0 5 votes vote down vote up
public static byte[] getArray(ByteBuf buffer) {
    if (buffer.hasArray() && buffer.arrayOffset() == 0 && buffer.writableBytes() == 0) {
        return buffer.array();
    }
    byte[] data = new byte[buffer.readableBytes()];
    buffer.getBytes(buffer.readerIndex(), data);
    return data;
}
 
Example 6
Source File: SpdyHeaderBlockZlibEncoder.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
private boolean compressInto(ByteBuf compressed) {
    byte[] out = compressed.array();
    int off = compressed.arrayOffset() + compressed.writerIndex();
    int toWrite = compressed.writableBytes();
    int numBytes = compressor.deflate(out, off, toWrite, Deflater.SYNC_FLUSH);
    compressed.writerIndex(compressed.writerIndex() + numBytes);
    return numBytes == toWrite;
}
 
Example 7
Source File: FlexBase64.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
/**
 * Encodes bytes read from source and writes them in base64 format to target. If the source limit is hit, this
 * method will return and save the current state, such that future calls can resume the encoding process.
 * In addition, if the target does not have the capacity to fit an entire quad of bytes, this method will also
 * return and save state for subsequent calls to this method. Once all bytes have been encoded to the target,
 * {@link #complete(java.nio.ByteBuf)} should be called to add the necessary padding characters.
 *
 * @param source the byte buffer to read from
 * @param target the byte buffer to write to
 */
public void encode(ByteBuf source, ByteBuf target) {
    if (target == null)
        throw new IllegalStateException();

    int last = this.last;
    int state = this.state;
    boolean wrap = this.wrap;
    int count = this.count;
    final byte[] ENCODING_TABLE = encodingTable;

    int remaining = source.readableBytes();
    while (remaining > 0) {
        // Unrolled state machine for performance (resumes and executes all states in one iteration)
        int require = 4 - state;
        require = wrap && (count >= 72) ? require + 2 : require;
        if (target.writableBytes() < require) {
            break;
        }
        //  ( 6 | 2) (4 | 4) (2 | 6)
        int b = source.readByte() & 0xFF;
        if (state == 0) {
            target.writeByte(ENCODING_TABLE[b >>> 2]);
            last = (b & 0x3) << 4;
            state++;
            if (--remaining <= 0) {
                break;
            }
            b = source.readByte() & 0xFF;
        }
        if (state == 1) {
            target.writeByte(ENCODING_TABLE[last | (b >>> 4)]);
            last = (b & 0x0F) << 2;
            state++;
            if (--remaining <= 0) {
                break;
            }
            b = source.readByte() & 0xFF;
        }
        if (state == 2) {
            target.writeByte(ENCODING_TABLE[last | (b >>> 6)]);
            target.writeByte(ENCODING_TABLE[b & 0x3F]);
            last = state = 0;
            remaining--;
        }

        if (wrap) {
            count += 4;
            if (count >= 76) {
                count = 0;
                target.writeShort((short) 0x0D0A);
            }
        }
    }
    this.count = count;
    this.last = last;
    this.state = state;
    this.lastPos = source.readerIndex();
}
 
Example 8
Source File: FlexBase64.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
/**
 * Decodes one Base64 byte buffer into another. This method will return and save state
 * if the target does not have the required capacity. Subsequent calls with a new target will
 * resume reading where it last left off (the source buffer's position). Similarly not all of the
 * source data need be available, this method can be repetitively called as data is made available.
 * <p>
 * <p>The decoder will skip white space, but will error if it detects corruption.</p>
 *
 * @param source the byte buffer to read encoded data from
 * @param target the byte buffer to write decoded data to
 * @throws IOException if the encoded data is corrupted
 */
public void decode(ByteBuf source, ByteBuf target) throws IOException {
    if (target == null)
        throw new IllegalStateException();

    int last = this.last;
    int state = this.state;

    int remaining = source.readableBytes();
    int targetRemaining = target.writableBytes();
    int b = 0;
    while (remaining-- > 0 && targetRemaining > 0) {
        b = nextByte(source, state, last, false);
        if (b == MARK) {
            last = MARK;
            if (--remaining <= 0) {
                break;
            }
            b = nextByte(source, state, last, false);
        }
        if (b == DONE) {
            last = state = 0;
            break;
        }
        if (b == SKIP) {
            continue;
        }
        //  ( 6 | 2) (4 | 4) (2 | 6)
        if (state == 0) {
            last = b << 2;
            state++;
            if (remaining-- <= 0) {
                break;
            }
            b = nextByte(source, state, last, false);
            if ((b & 0xF000) != 0) {
                source.readerIndex(source.readerIndex() - 1);
                continue;
            }
        }
        if (state == 1) {
            target.writeByte((byte) (last | (b >>> 4)));
            last = (b & 0x0F) << 4;
            state++;
            if (remaining-- <= 0 || --targetRemaining <= 0) {
                break;
            }
            b = nextByte(source, state, last, false);
            if ((b & 0xF000) != 0) {
                source.writeInt(source.writerIndex() - 1);
                continue;
            }
        }
        if (state == 2) {
            target.writeByte((byte) (last | (b >>> 2)));
            last = (b & 0x3) << 6;
            state++;
            if (remaining-- <= 0 || --targetRemaining <= 0) {
                break;
            }
            b = nextByte(source, state, last, false);
            if ((b & 0xF000) != 0) {
                source.readerIndex(source.readerIndex() - 1);
                continue;
            }
        }
        if (state == 3) {
            target.writeByte((byte) (last | b));
            last = state = 0;
            targetRemaining--;
        }
    }

    if (remaining > 0) {
        drain(source, b, state, last);
    }

    this.last = last;
    this.state = state;
    this.lastPos = source.readerIndex();
}
 
Example 9
Source File: HttpObjectEncoder.java    From netty4.0.27Learn with Apache License 2.0 4 votes vote down vote up
@Override
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
    ByteBuf buf = null;
    if (msg instanceof HttpMessage) {
        if (state != ST_INIT) {
            throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg));
        }

        @SuppressWarnings({ "unchecked", "CastConflictsWithInstanceof" })
        H m = (H) msg;

        buf = ctx.alloc().buffer();
        // Encode the message.
        encodeInitialLine(buf, m);
        encodeHeaders(m.headers(), buf);
        buf.writeBytes(CRLF);
        state = HttpHeaders.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK;
    }

    // Bypass the encoder in case of an empty buffer, so that the following idiom works:
    //
    //     ch.write(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    //
    // See https://github.com/netty/netty/issues/2983 for more information.

    if (msg instanceof ByteBuf && !((ByteBuf) msg).isReadable()) {
        out.add(EMPTY_BUFFER);
        return;
    }

    if (msg instanceof HttpContent || msg instanceof ByteBuf || msg instanceof FileRegion) {

        if (state == ST_INIT) {
            throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg));
        }

        final long contentLength = contentLength(msg);
        if (state == ST_CONTENT_NON_CHUNK) {
            if (contentLength > 0) {
                if (buf != null && buf.writableBytes() >= contentLength && msg instanceof HttpContent) {
                    // merge into other buffer for performance reasons
                    buf.writeBytes(((HttpContent) msg).content());
                    out.add(buf);
                } else {
                    if (buf != null) {
                        out.add(buf);
                    }
                    out.add(encodeAndRetain(msg));
                }
            } else {
                if (buf != null) {
                    out.add(buf);
                } else {
                    // Need to produce some output otherwise an
                    // IllegalStateException will be thrown
                    out.add(EMPTY_BUFFER);
                }
            }

            if (msg instanceof LastHttpContent) {
                state = ST_INIT;
            }
        } else if (state == ST_CONTENT_CHUNK) {
            if (buf != null) {
                out.add(buf);
            }
            encodeChunkedContent(ctx, msg, contentLength, out);
        } else {
            throw new Error();
        }
    } else {
        if (buf != null) {
            out.add(buf);
        }
    }
}
 
Example 10
Source File: AbstractNioByteChannel.java    From netty4.0.27Learn with Apache License 2.0 4 votes vote down vote up
@Override
public final void read() {
    final ChannelConfig config = config();
    if (!config.isAutoRead() && !isReadPending()) {
        // ChannelConfig.setAutoRead(false) was called in the meantime
        removeReadOp();
        return;
    }

    final ChannelPipeline pipeline = pipeline();
    final ByteBufAllocator allocator = config.getAllocator();
    final int maxMessagesPerRead = config.getMaxMessagesPerRead();
    RecvByteBufAllocator.Handle allocHandle = this.allocHandle;
    if (allocHandle == null) {
        this.allocHandle = allocHandle = config.getRecvByteBufAllocator().newHandle();
    }

    ByteBuf byteBuf = null;
    int messages = 0;
    boolean close = false;
    try {
        int totalReadAmount = 0;
        boolean readPendingReset = false;
        do {
            byteBuf = allocHandle.allocate(allocator);
            int writable = byteBuf.writableBytes();
            int localReadAmount = doReadBytes(byteBuf);
            if (localReadAmount <= 0) {
                // not was read release the buffer
                byteBuf.release();
                byteBuf = null;
                close = localReadAmount < 0;
                break;
            }
            if (!readPendingReset) {
                readPendingReset = true;
                setReadPending(false);
            }
            pipeline.fireChannelRead(byteBuf);
            byteBuf = null;

            if (totalReadAmount >= Integer.MAX_VALUE - localReadAmount) {
                // Avoid overflow.
                totalReadAmount = Integer.MAX_VALUE;
                break;
            }

            totalReadAmount += localReadAmount;

            // stop reading
            if (!config.isAutoRead()) {
                break;
            }

            if (localReadAmount < writable) {
                // Read less than what the buffer can hold,
                // which might mean we drained the recv buffer completely.
                break;
            }
        } while (++ messages < maxMessagesPerRead);

        pipeline.fireChannelReadComplete();
        allocHandle.record(totalReadAmount);

        if (close) {
            closeOnRead(pipeline);
            close = false;
        }
    } catch (Throwable t) {
        handleReadException(pipeline, byteBuf, t, close);
    } finally {
        // Check if there is a readPending which was not processed yet.
        // This could be for two reasons:
        // * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...) method
        // * The user called Channel.read() or ChannelHandlerContext.read() in channelReadComplete(...) method
        //
        // See https://github.com/netty/netty/issues/2254
        if (!config.isAutoRead() && !isReadPending()) {
            removeReadOp();
        }
    }
}
 
Example 11
Source File: AbstractEpollStreamChannel.java    From netty4.0.27Learn with Apache License 2.0 4 votes vote down vote up
@Override
void epollInReady() {
    final ChannelConfig config = config();
    boolean edgeTriggered = isFlagSet(Native.EPOLLET);

    if (!readPending && !edgeTriggered && !config.isAutoRead()) {
        // ChannelConfig.setAutoRead(false) was called in the meantime
        clearEpollIn0();
        return;
    }

    final ChannelPipeline pipeline = pipeline();
    final ByteBufAllocator allocator = config.getAllocator();
    RecvByteBufAllocator.Handle allocHandle = this.allocHandle;
    if (allocHandle == null) {
        this.allocHandle = allocHandle = config.getRecvByteBufAllocator().newHandle();
    }

    ByteBuf byteBuf = null;
    boolean close = false;
    try {
        // if edgeTriggered is used we need to read all messages as we are not notified again otherwise.
        final int maxMessagesPerRead = edgeTriggered
                ? Integer.MAX_VALUE : config.getMaxMessagesPerRead();
        int messages = 0;
        int totalReadAmount = 0;
        do {
            // we use a direct buffer here as the native implementations only be able
            // to handle direct buffers.
            byteBuf = allocHandle.allocate(allocator);
            int writable = byteBuf.writableBytes();
            int localReadAmount = doReadBytes(byteBuf);
            if (localReadAmount <= 0) {
                // not was read release the buffer
                byteBuf.release();
                close = localReadAmount < 0;
                break;
            }
            readPending = false;
            pipeline.fireChannelRead(byteBuf);
            byteBuf = null;

            if (totalReadAmount >= Integer.MAX_VALUE - localReadAmount) {
                allocHandle.record(totalReadAmount);

                // Avoid overflow.
                totalReadAmount = localReadAmount;
            } else {
                totalReadAmount += localReadAmount;
            }

            if (localReadAmount < writable) {
                // Read less than what the buffer can hold,
                // which might mean we drained the recv buffer completely.
                break;
            }
            if (!edgeTriggered && !config.isAutoRead()) {
                // This is not using EPOLLET so we can stop reading
                // ASAP as we will get notified again later with
                // pending data
                break;
            }
        } while (++ messages < maxMessagesPerRead);

        pipeline.fireChannelReadComplete();
        allocHandle.record(totalReadAmount);

        if (close) {
            closeOnRead(pipeline);
            close = false;
        }
    } catch (Throwable t) {
        boolean closed = handleReadException(pipeline, byteBuf, t, close);
        if (!closed) {
            // trigger a read again as there may be something left to read and because of epoll ET we
            // will not get notified again until we read everything from the socket
            eventLoop().execute(new Runnable() {
                @Override
                public void run() {
                    epollInReady();
                }
            });
        }
    } finally {
        // Check if there is a readPending which was not processed yet.
        // This could be for two reasons:
        // * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...) method
        // * The user called Channel.read() or ChannelHandlerContext.read() in channelReadComplete(...) method
        //
        // See https://github.com/netty/netty/issues/2254
        if (!readPending && !config.isAutoRead()) {
            clearEpollIn0();
        }
    }
}
 
Example 12
Source File: NettyMonitorIO.java    From netty-cookbook with Apache License 2.0 4 votes vote down vote up
public static long updateDataIn(ByteBuf buf) {
	String time = DATE_TIME_FORMAT.format(new Date());
	long c = dataInStats.getOrDefault(time, 0L) + buf.writableBytes();
	dataInStats.put(time, c);
	return c;
}
 
Example 13
Source File: NettyMonitorIO.java    From netty-cookbook with Apache License 2.0 4 votes vote down vote up
public static long updateDataIn(ByteBuf buf) {
	String time = DATE_TIME_FORMAT.format(new Date());
	long c = dataInStats.getOrDefault(time, 0L) + buf.writableBytes();
	dataInStats.put(time, c);
	return c;
}
 
Example 14
Source File: AbstractXnioSocketChannel.java    From netty-xnio-transport with Apache License 2.0 4 votes vote down vote up
@Override
public void handleEvent(ConduitStreamSourceChannel channel) {
    final ChannelConfig config = config();
    final ChannelPipeline pipeline = pipeline();
    final ByteBufAllocator allocator = config.getAllocator();
    final int maxMessagesPerRead = config.getMaxMessagesPerRead();
    RecvByteBufAllocator.Handle allocHandle = this.allocHandle;
    if (allocHandle == null) {
        this.allocHandle = allocHandle = config.getRecvByteBufAllocator().newHandle();
    }

    ByteBuf byteBuf = null;
    int messages = 0;
    boolean close = false;
    try {
        int byteBufCapacity = allocHandle.guess();
        int totalReadAmount = 0;
        do {
            byteBuf = allocator.ioBuffer(byteBufCapacity);
            int writable = byteBuf.writableBytes();
            int localReadAmount = byteBuf.writeBytes(channel, byteBuf.writableBytes());
            if (localReadAmount <= 0) {
                // not was read release the buffer
                byteBuf.release();
                close = localReadAmount < 0;
                break;
            }
            ((AbstractXnioUnsafe) unsafe()).readPending = false;
            pipeline.fireChannelRead(byteBuf);
            byteBuf = null;

            if (totalReadAmount >= Integer.MAX_VALUE - localReadAmount) {
                // Avoid overflow.
                totalReadAmount = Integer.MAX_VALUE;
                break;
            }

            totalReadAmount += localReadAmount;

            // stop reading
            if (!config.isAutoRead()) {
                break;
            }

            if (localReadAmount < writable) {
                // Read less than what the buffer can hold,
                // which might mean we drained the recv buffer completely.
                break;
            }
        } while (++ messages < maxMessagesPerRead);

        pipeline.fireChannelReadComplete();
        allocHandle.record(totalReadAmount);

        if (close) {
            closeOnRead();
            close = false;
        }
    } catch (Throwable t) {
        handleReadException(pipeline, byteBuf, t, close);
    } finally {
        // Check if there is a readPending which was not processed yet.
        // This could be for two reasons:
        // * The user called Channel.read() or ChannelHandlerContext.read() in channelRead(...) method
        // * The user called Channel.read() or ChannelHandlerContext.read() in channelReadComplete(...) method
        //
        // See https://github.com/netty/netty/issues/2254
        if (!config.isAutoRead() && !((AbstractXnioUnsafe) unsafe()).readPending) {
            removeReadOp(channel);
        }
    }
}