@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();
      }
    }
  }
Example #2
0
 @Override
 @Deprecated
 public boolean writable() {
   return buf.writable();
 }