@Override protected void doRead() { if (checkInputShutdown()) { return; } final ChannelPipeline pipeline = pipeline(); final ByteBuf byteBuf = pipeline.inboundByteBuffer(); boolean closed = false; boolean read = false; boolean firedInboundBufferSuspeneded = false; try { for (; ; ) { int localReadAmount = doReadBytes(byteBuf); if (localReadAmount > 0) { read = true; } else if (localReadAmount < 0) { closed = true; } final int available = available(); if (available <= 0) { break; } if (byteBuf.writable()) { continue; } final int capacity = byteBuf.capacity(); final int maxCapacity = byteBuf.maxCapacity(); if (capacity == maxCapacity) { if (read) { read = false; pipeline.fireInboundBufferUpdated(); if (!byteBuf.writable()) { throw new IllegalStateException( "an inbound handler whose buffer is full must consume at " + "least one byte."); } } } else { final int writerIndex = byteBuf.writerIndex(); if (writerIndex + available > maxCapacity) { byteBuf.capacity(maxCapacity); } else { byteBuf.ensureWritableBytes(available); } } } } catch (Throwable t) { if (read) { read = false; pipeline.fireInboundBufferUpdated(); } if (t instanceof IOException) { closed = true; pipeline.fireExceptionCaught(t); } else { firedInboundBufferSuspeneded = true; pipeline.fireInboundBufferSuspended(); pipeline.fireExceptionCaught(t); unsafe().close(unsafe().voidFuture()); } } finally { if (read) { pipeline.fireInboundBufferUpdated(); } if (closed) { inputShutdown = true; if (isOpen()) { if (Boolean.TRUE.equals(config().getOption(ChannelOption.ALLOW_HALF_CLOSURE))) { pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE); } else { unsafe().close(unsafe().voidFuture()); } } } else if (!firedInboundBufferSuspeneded) { pipeline.fireInboundBufferSuspended(); } } }
@Override @Deprecated public boolean writable() { return buf.writable(); }