Example #1
0
  /**
   * Puts {@code numBits} into the buffer with the value {@code value}.
   *
   * @param numBits The number of bits to put into the buffer.
   * @param value The value.
   * @throws IllegalStateException if the builder is not in bit access mode.
   * @throws IllegalArgumentException if the number of bits is not between 1 and 31 inclusive.
   */
  public void putBits(int numBits, int value) {
    if (numBits <= 0 || numBits > 32) {
      throw new IllegalArgumentException("Number of bits must be between 1 and 31 inclusive");
    }

    checkBitAccess();

    int bytePos = bitIndex >> 3;
    int bitOffset = 8 - (bitIndex & 7);
    bitIndex += numBits;

    int requiredSpace = bytePos - buffer.writerIndex() + 1;
    requiredSpace += (numBits + 7) / 8;
    buffer.ensureWritable(requiredSpace);

    for (; numBits > bitOffset; bitOffset = 8) {
      int tmp = buffer.getByte(bytePos);
      tmp &= ~BITMASKS[bitOffset];
      tmp |= (value >> (numBits - bitOffset)) & BITMASKS[bitOffset];
      buffer.setByte(bytePos++, tmp);
      numBits -= bitOffset;
    }
    if (numBits == bitOffset) {
      int tmp = buffer.getByte(bytePos);
      tmp &= ~BITMASKS[bitOffset];
      tmp |= value & BITMASKS[bitOffset];
      buffer.setByte(bytePos, tmp);
    } else {
      int tmp = buffer.getByte(bytePos);
      tmp &= ~(BITMASKS[numBits] << (bitOffset - numBits));
      tmp |= (value & BITMASKS[numBits]) << (bitOffset - numBits);
      buffer.setByte(bytePos, tmp);
    }
  }
Example #2
0
 private void ensureWritable(int pos, int len) {
   int ni = pos + len;
   int cap = buffer.capacity();
   int over = ni - cap;
   if (over > 0) {
     buffer.writerIndex(cap);
     buffer.ensureWritable(over);
   }
   // We have to make sure that the writerindex is always positioned on the last bit of data set in
   // the buffer
   if (ni > buffer.writerIndex()) {
     buffer.writerIndex(ni);
   }
 }
Example #3
0
 private static SSLEngineResult unwrap(SSLEngine engine, ByteBuffer in, ByteBuf out)
     throws SSLException {
   int overflows = 0;
   for (; ; ) {
     ByteBuffer out0 = out.nioBuffer(out.writerIndex(), out.writableBytes());
     SSLEngineResult result = engine.unwrap(in, out0);
     out.writerIndex(out.writerIndex() + result.bytesProduced());
     switch (result.getStatus()) {
       case BUFFER_OVERFLOW:
         int max = engine.getSession().getApplicationBufferSize();
         switch (overflows++) {
           case 0:
             out.ensureWritable(Math.min(max, in.remaining()));
             break;
           default:
             out.ensureWritable(max);
         }
         break;
       default:
         return result;
     }
   }
 }
Example #4
0
  private SSLEngineResult wrap(SSLEngine engine, ByteBuf in, ByteBuf out) throws SSLException {
    ByteBuffer in0 = in.nioBuffer();
    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;
      }
    }
  }
Example #5
0
  @Override
  protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
    if (msg instanceof SpdyDataFrame) {

      SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
      ByteBuf data = spdyDataFrame.data();
      byte flags = spdyDataFrame.isLast() ? SPDY_DATA_FLAG_FIN : 0;
      out.ensureWritable(SPDY_HEADER_SIZE + data.readableBytes());
      out.writeInt(spdyDataFrame.getStreamId() & 0x7FFFFFFF);
      out.writeByte(flags);
      out.writeMedium(data.readableBytes());
      out.writeBytes(data, data.readerIndex(), data.readableBytes());

    } else if (msg instanceof SpdySynStreamFrame) {

      SpdySynStreamFrame spdySynStreamFrame = (SpdySynStreamFrame) msg;
      ByteBuf data = compressHeaderBlock(encodeHeaderBlock(version, spdySynStreamFrame));
      byte flags = spdySynStreamFrame.isLast() ? SPDY_FLAG_FIN : 0;
      if (spdySynStreamFrame.isUnidirectional()) {
        flags |= SPDY_FLAG_UNIDIRECTIONAL;
      }
      int headerBlockLength = data.readableBytes();
      int length;
      if (version < 3) {
        length = headerBlockLength == 0 ? 12 : 10 + headerBlockLength;
      } else {
        length = 10 + headerBlockLength;
      }
      out.ensureWritable(SPDY_HEADER_SIZE + length);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_SYN_STREAM_FRAME);
      out.writeByte(flags);
      out.writeMedium(length);
      out.writeInt(spdySynStreamFrame.getStreamId());
      out.writeInt(spdySynStreamFrame.getAssociatedToStreamId());
      if (version < 3) {
        // Restrict priorities for SPDY/2 to between 0 and 3
        byte priority = spdySynStreamFrame.getPriority();
        if (priority > 3) {
          priority = 3;
        }
        out.writeShort((priority & 0xFF) << 14);
      } else {
        out.writeShort((spdySynStreamFrame.getPriority() & 0xFF) << 13);
      }
      if (version < 3 && data.readableBytes() == 0) {
        out.writeShort(0);
      }
      out.writeBytes(data, data.readerIndex(), headerBlockLength);

    } else if (msg instanceof SpdySynReplyFrame) {

      SpdySynReplyFrame spdySynReplyFrame = (SpdySynReplyFrame) msg;
      ByteBuf data = compressHeaderBlock(encodeHeaderBlock(version, spdySynReplyFrame));
      byte flags = spdySynReplyFrame.isLast() ? SPDY_FLAG_FIN : 0;
      int headerBlockLength = data.readableBytes();
      int length;
      if (version < 3) {
        length = headerBlockLength == 0 ? 8 : 6 + headerBlockLength;
      } else {
        length = 4 + headerBlockLength;
      }
      out.ensureWritable(SPDY_HEADER_SIZE + length);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_SYN_REPLY_FRAME);
      out.writeByte(flags);
      out.writeMedium(length);
      out.writeInt(spdySynReplyFrame.getStreamId());
      if (version < 3) {
        if (headerBlockLength == 0) {
          out.writeInt(0);
        } else {
          out.writeShort(0);
        }
      }
      out.writeBytes(data, data.readerIndex(), headerBlockLength);

    } else if (msg instanceof SpdyRstStreamFrame) {

      SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
      out.ensureWritable(SPDY_HEADER_SIZE + 8);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_RST_STREAM_FRAME);
      out.writeInt(8);
      out.writeInt(spdyRstStreamFrame.getStreamId());
      out.writeInt(spdyRstStreamFrame.getStatus().getCode());

    } else if (msg instanceof SpdySettingsFrame) {

      SpdySettingsFrame spdySettingsFrame = (SpdySettingsFrame) msg;
      byte flags = spdySettingsFrame.clearPreviouslyPersistedSettings() ? SPDY_SETTINGS_CLEAR : 0;
      Set<Integer> IDs = spdySettingsFrame.getIds();
      int numEntries = IDs.size();
      int length = 4 + numEntries * 8;
      out.ensureWritable(SPDY_HEADER_SIZE + length);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_SETTINGS_FRAME);
      out.writeByte(flags);
      out.writeMedium(length);
      out.writeInt(numEntries);
      for (Integer ID : IDs) {
        int id = ID.intValue();
        byte ID_flags = 0;
        if (spdySettingsFrame.isPersistValue(id)) {
          ID_flags |= SPDY_SETTINGS_PERSIST_VALUE;
        }
        if (spdySettingsFrame.isPersisted(id)) {
          ID_flags |= SPDY_SETTINGS_PERSISTED;
        }
        if (version < 3) {
          // Chromium Issue 79156
          // SPDY setting ids are not written in network byte order
          // Write id assuming the architecture is little endian
          out.writeByte(id & 0xFF);
          out.writeByte(id >> 8 & 0xFF);
          out.writeByte(id >> 16 & 0xFF);
          out.writeByte(ID_flags);
        } else {
          out.writeByte(ID_flags);
          out.writeMedium(id);
        }
        out.writeInt(spdySettingsFrame.getValue(id));
      }

    } else if (msg instanceof SpdyNoOpFrame) {

      out.ensureWritable(SPDY_HEADER_SIZE);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_NOOP_FRAME);
      out.writeInt(0);

    } else if (msg instanceof SpdyPingFrame) {

      SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg;
      out.ensureWritable(SPDY_HEADER_SIZE + 4);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_PING_FRAME);
      out.writeInt(4);
      out.writeInt(spdyPingFrame.getId());

    } else if (msg instanceof SpdyGoAwayFrame) {

      SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg;
      int length = version < 3 ? 4 : 8;
      out.ensureWritable(SPDY_HEADER_SIZE + length);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_GOAWAY_FRAME);
      out.writeInt(length);
      out.writeInt(spdyGoAwayFrame.getLastGoodStreamId());
      if (version >= 3) {
        out.writeInt(spdyGoAwayFrame.getStatus().getCode());
      }

    } else if (msg instanceof SpdyHeadersFrame) {

      SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg;
      ByteBuf data = compressHeaderBlock(encodeHeaderBlock(version, spdyHeadersFrame));
      byte flags = spdyHeadersFrame.isLast() ? SPDY_FLAG_FIN : 0;
      int headerBlockLength = data.readableBytes();
      int length;
      if (version < 3) {
        length = headerBlockLength == 0 ? 4 : 6 + headerBlockLength;
      } else {
        length = 4 + headerBlockLength;
      }
      out.ensureWritable(SPDY_HEADER_SIZE + length);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_HEADERS_FRAME);
      out.writeByte(flags);
      out.writeMedium(length);
      out.writeInt(spdyHeadersFrame.getStreamId());
      if (version < 3 && headerBlockLength != 0) {
        out.writeShort(0);
      }
      out.writeBytes(data, data.readerIndex(), headerBlockLength);

    } else if (msg instanceof SpdyWindowUpdateFrame) {

      SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg;
      out.ensureWritable(SPDY_HEADER_SIZE + 8);
      out.writeShort(version | 0x8000);
      out.writeShort(SPDY_WINDOW_UPDATE_FRAME);
      out.writeInt(8);
      out.writeInt(spdyWindowUpdateFrame.getStreamId());
      out.writeInt(spdyWindowUpdateFrame.getDeltaWindowSize());
    } else {
      throw new UnsupportedMessageTypeException(msg);
    }
  }
  @Override
  protected void doRead() {
    if (checkInputShutdown()) {
      return;
    }

    final ChannelPipeline pipeline = pipeline();

    // TODO: calculate size as in 3.x
    ByteBuf byteBuf = alloc().buffer();
    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.isWritable()) {
          final int capacity = byteBuf.capacity();
          final int maxCapacity = byteBuf.maxCapacity();
          if (capacity == maxCapacity) {
            if (read) {
              read = false;
              pipeline.fireMessageReceived(byteBuf);
              byteBuf = alloc().buffer();
            }
          } else {
            final int writerIndex = byteBuf.writerIndex();
            if (writerIndex + available > maxCapacity) {
              byteBuf.capacity(maxCapacity);
            } else {
              byteBuf.ensureWritable(available);
            }
          }
        }
        if (!config().isAutoRead()) {
          // stop reading until next Channel.read() call
          // See https://github.com/netty/netty/issues/1363
          break;
        }
      }
    } catch (Throwable t) {
      if (read) {
        read = false;
        pipeline.fireMessageReceived(byteBuf);
      }

      if (t instanceof IOException) {
        closed = true;
        pipeline.fireExceptionCaught(t);
      } else {
        firedInboundBufferSuspeneded = true;
        pipeline.fireChannelReadSuspended();
        pipeline.fireExceptionCaught(t);
        unsafe().close(voidPromise());
      }
    } finally {
      if (read) {
        pipeline.fireMessageReceived(byteBuf);
      } else {
        // nothing read into the buffer so release it
        byteBuf.release();
      }
      if (closed) {
        inputShutdown = true;
        if (isOpen()) {
          if (Boolean.TRUE.equals(config().getOption(ChannelOption.ALLOW_HALF_CLOSURE))) {
            pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
          } else {
            unsafe().close(unsafe().voidPromise());
          }
        }
      } else if (!firedInboundBufferSuspeneded) {
        pipeline.fireChannelReadSuspended();
      }
    }
  }
Example #7
0
  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();
      }
    }
  }
Example #8
0
 @Override
 public int ensureWritable(int minWritableBytes, boolean force) {
   return buf.ensureWritable(minWritableBytes, force);
 }
Example #9
0
 @Override
 public ByteBuf ensureWritable(int minWritableBytes) {
   return buf.ensureWritable(minWritableBytes);
 }
 @Override
 public int ensureWritable(int var1, boolean var2) {
   return a.ensureWritable(var1, var2);
 }
 @Override
 public ByteBuf ensureWritable(int var1) {
   return a.ensureWritable(var1);
 }