public void readData(ByteBuf data) {
   id = data.readShort();
   parseData(data.readUnsignedShort(), data.readUnsignedByte());
   dX = data.readFloat();
   dY = data.readFloat();
   dZ = data.readFloat();
 }
Example #2
0
 public RegisterMessage decode(ByteBuf body, int version) {
   int length = body.readUnsignedShort();
   List<Event.Type> eventTypes = new ArrayList<Event.Type>(length);
   for (int i = 0; i < length; ++i)
     eventTypes.add(CBUtil.readEnumValue(Event.Type.class, body));
   return new RegisterMessage(eventTypes);
 }
 @Override
 protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out)
     throws Exception {
   switch (state()) {
     case CHECK_NULL_BYTE:
       {
         if (byteBuf.readByte() != (byte) 0x00) {
           break;
         }
         checkpoint(State.READ_CMD_HEADER);
       }
     case READ_CMD_HEADER:
       {
         cmdStatus = Socks4CmdStatus.valueOf(byteBuf.readByte());
         checkpoint(State.READ_CMD_ADDRESS);
       }
     case READ_CMD_ADDRESS:
       {
         port = byteBuf.readUnsignedShort();
         host = Socks4CommonUtils.intToIp(byteBuf.readInt());
         msg = new Socks4CmdResponse(cmdStatus, host, port);
       }
   }
   ctx.pipeline().remove(this);
   out.add(msg);
 }
 private void readSettingsFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameListener listener)
     throws Http2Exception {
   if (flags.ack()) {
     listener.onSettingsAckRead(ctx);
   } else {
     int numSettings = payloadLength / SETTING_ENTRY_LENGTH;
     Http2Settings settings = new Http2Settings();
     for (int index = 0; index < numSettings; ++index) {
       char id = (char) payload.readUnsignedShort();
       long value = payload.readUnsignedInt();
       try {
         settings.put(id, Long.valueOf(value));
       } catch (IllegalArgumentException e) {
         switch (id) {
           case SETTINGS_MAX_FRAME_SIZE:
             throw connectionError(FRAME_SIZE_ERROR, e, e.getMessage());
           case SETTINGS_INITIAL_WINDOW_SIZE:
             throw connectionError(FLOW_CONTROL_ERROR, e, e.getMessage());
           default:
             throw connectionError(PROTOCOL_ERROR, e, e.getMessage());
         }
       }
     }
     listener.onSettingsRead(ctx, settings);
   }
 }
 private static void checkHeader(ByteBuf buffer, boolean hasMask) {
   assertEquals(
       "Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort());
   short fieldAndMask = buffer.readUnsignedByte();
   assertEquals("Wrong oxm-field", OxmMatchConstants.SCTP_DST, fieldAndMask >>> 1);
   assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0);
   assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte());
 }
Example #6
0
 @Override
 public HandshakeMessage decode(ByteBuf buf) throws IOException {
   final int version = ByteBufUtils.readVarInt(buf);
   final String address = ByteBufUtils.readUTF8(buf);
   final short port = (short) buf.readUnsignedShort();
   final HandshakeState state = HandshakeState.get(ByteBufUtils.readVarInt(buf));
   return new HandshakeMessage(version, address, port, state);
 }
Example #7
0
 /**
  * This method will first read an unsigned short to find the length of the string and then read
  * the actual string based on the length. This method will also reset the reader index to end of
  * the string
  *
  * @param buffer The Netty buffer containing at least one unsigned short followed by a string of
  *     similar length.
  * @param charset The Charset say 'UTF-8' in which the decoding needs to be done.
  * @return Returns the String or throws {@link IndexOutOfBoundsException} if the length is greater
  *     than expected.
  */
 public static String readString(ByteBuf buffer, Charset charset) {
   String readString = null;
   if (null != buffer && buffer.readableBytes() > 2) {
     int length = buffer.readUnsignedShort();
     readString = readString(buffer, length, charset);
   }
   return readString;
 }
  @Override
  public void decode(ByteBuf data) {
    byteCount = data.readUnsignedByte();

    registers = new int[byteCount / 2];
    for (int i = 0; i < registers.length; i++) {
      registers[i] = data.readUnsignedShort();
    }
  }
  private void processHeaderState(ByteBuf in) throws Http2Exception {
    if (in.readableBytes() < FRAME_HEADER_LENGTH) {
      // Wait until the entire frame header has been read.
      return;
    }

    // Read the header and prepare the unmarshaller to read the frame.
    payloadLength = in.readUnsignedShort() & FRAME_LENGTH_MASK;
    frameType = Http2FrameType.forTypeCode(in.readUnsignedByte());
    flags = new Http2Flags(in.readUnsignedByte());
    streamId = readUnsignedInt(in);

    switch (frameType) {
      case DATA:
        verifyDataFrame();
        break;
      case HEADERS:
        verifyHeadersFrame();
        break;
      case PRIORITY:
        verifyPriorityFrame();
        break;
      case RST_STREAM:
        verifyRstStreamFrame();
        break;
      case SETTINGS:
        verifySettingsFrame();
        break;
      case PUSH_PROMISE:
        verifyPushPromiseFrame();
        break;
      case PING:
        verifyPingFrame();
        break;
      case GO_AWAY:
        verifyGoAwayFrame();
        break;
      case WINDOW_UPDATE:
        verifyWindowUpdateFrame();
        break;
      case CONTINUATION:
        verifyContinuationFrame();
        break;
      case ALT_SVC:
        verifyAltSvcFrame();
        break;
      case BLOCKED:
        verifyBlockedFrame();
        break;
      default:
        throw protocolError("Unsupported frame type: %s", frameType);
    }

    // Start reading the payload for the frame.
    state = State.FRAME_PAYLOAD;
  }
 @Override
 public GetQueueConfigOutput deserialize(ByteBuf rawMessage) {
   GetQueueConfigOutputBuilder builder = new GetQueueConfigOutputBuilder();
   builder.setVersion((short) EncodeConstants.OF10_VERSION_ID);
   builder.setXid((rawMessage.readUnsignedInt()));
   builder.setPort(new PortNumber((long) rawMessage.readUnsignedShort()));
   rawMessage.skipBytes(PADDING_IN_QUEUE_GET_CONFIG_REPLY_HEADER);
   builder.setQueues(createQueuesList(rawMessage));
   return builder.build();
 }
 private static List<QueueProperty> createPropertiesList(ByteBuf input, int length) {
   int propertiesLength = length;
   List<QueueProperty> propertiesList = new ArrayList<>();
   while (propertiesLength > 0) {
     QueuePropertyBuilder propertiesBuilder = new QueuePropertyBuilder();
     QueueProperties property = QueueProperties.forValue(input.readUnsignedShort());
     propertiesBuilder.setProperty(property);
     propertiesLength -= input.readUnsignedShort();
     input.skipBytes(PADDING_IN_QUEUE_PROPERTY_HEADER);
     if (property.equals(QueueProperties.OFPQTMINRATE)) {
       RateQueuePropertyBuilder rateBuilder = new RateQueuePropertyBuilder();
       rateBuilder.setRate(input.readUnsignedShort());
       propertiesBuilder.addAugmentation(RateQueueProperty.class, rateBuilder.build());
       input.skipBytes(PADDING_IN_RATE_QUEUE_PROPERTY);
     }
     propertiesList.add(propertiesBuilder.build());
   }
   return propertiesList;
 }
  /** Test correct serialization */
  @Test
  public void testSerialize() {
    MatchEntryBuilder builder = prepareMatchEntry(4096);

    ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer();
    serializer.serialize(builder.build(), buffer);

    checkHeader(buffer, false);
    assertEquals("Wrong value", 4096, buffer.readUnsignedShort());
    assertTrue("Unexpected data", buffer.readableBytes() == 0);
  }
 @Override
 public Tlv parseTlv(final ByteBuf buffer) throws BmpDeserializationException {
   if (buffer == null) {
     return null;
   }
   return new PerAfiSafiLocRibTlvBuilder()
       .setAfi(this.afiRegistry.classForFamily(buffer.readUnsignedShort()))
       .setSafi(this.safiRegistry.classForFamily(buffer.readUnsignedByte()))
       .setCount(new Gauge64(new BigInteger(ByteArray.readAllBytes(buffer))))
       .build();
 }
Example #14
0
  public static int readVarShort(ByteBuf buf) {
    int low = buf.readUnsignedShort();
    int high = 0;

    if ((low & 0x8000) != 0) {
      low = low & 0x7FFF;
      high = buf.readUnsignedByte();
    }

    return ((high & 0xFF) << 15) | low;
  }
  int decode(ByteBuf buf) {
    // ByteBuf bbuf = Unpooled.wrappedBuffer(buf);
    // ByteBuf tmpbuf = bbuf.readerIndex(pos);

    this.msgType = buf.readUnsignedInt();
    this.seqNo = buf.readUnsignedByte();
    this.msgLen = buf.readUnsignedShort();
    this.flags = buf.readUnsignedByte();

    return 0;
  }
 private static List<Queues> createQueuesList(ByteBuf input) {
   List<Queues> queuesList = new ArrayList<>();
   while (input.readableBytes() > 0) {
     QueuesBuilder queueBuilder = new QueuesBuilder();
     queueBuilder.setQueueId(new QueueId(input.readUnsignedInt()));
     int length = input.readUnsignedShort();
     input.skipBytes(PADDING_IN_PACKET_QUEUE_HEADER);
     queueBuilder.setQueueProperty(
         createPropertiesList(input, length - PACKET_QUEUE_HEADER_LENGTH));
     queuesList.add(queueBuilder.build());
   }
   return queuesList;
 }
 @Test
 public void testEncode() {
   MockRelayMessage message = new MockRelayMessage();
   message.code(Unsigned16.get(100));
   message.length(Unsigned32.get(36L));
   message.flag(new FlagData(FlagImpl.REQUEST));
   message.hopByHop(Integer64.get(1L));
   message.endToEnd(Integer64.get(2L));
   message.addAttribute(new IgnoredAttribute(new IgnoredData(new byte[] {1, 2, 3, 4})));
   ByteBuf buf = MessageFactory.getInstance().generateByteBuf(message);
   Assert.assertEquals(message.version().get().byteValue(), buf.readUnsignedByte());
   Assert.assertEquals(message.code().get().intValue(), buf.readUnsignedShort());
   assertEquals(64, buf.readUnsignedByte());
   Assert.assertEquals(message.length().get().intValue(), buf.readUnsignedInt());
   assertEquals(message.hopByHop().get().longValue(), buf.readLong());
   assertEquals(message.endToEnd().get().longValue(), buf.readLong());
   assertEquals(0, buf.readUnsignedShort());
   assertEquals(4, buf.readUnsignedInt());
   assertEquals(1, buf.readByte());
   assertEquals(2, buf.readByte());
   assertEquals(3, buf.readByte());
   assertEquals(4, buf.readByte());
 }
Example #18
0
  /**
   * Load a string from the given buffer, reading first the two bytes of len and then the UTF-8
   * bytes of the string.
   *
   * @return the decoded string or null if NEED_DATA
   */
  static String decodeString(ByteBuf in) throws UnsupportedEncodingException {
    if (in.readableBytes() < 2) {
      return null;
    }
    // int strLen = Utils.readWord(in);
    int strLen = in.readUnsignedShort();
    if (in.readableBytes() < strLen) {
      return null;
    }
    byte[] strRaw = new byte[strLen];
    in.readBytes(strRaw);

    return new String(strRaw, "UTF-8");
  }
Example #19
0
 public static <T, V> V readObject(ByteBuf buffer, Transform<ByteBuf, V> decoder) {
   int length = 0;
   if (null != buffer && buffer.readableBytes() > 2) {
     length = buffer.readUnsignedShort();
   } else {
     return null;
   }
   ByteBuf objBuffer = buffer.readSlice(length);
   V obj = null;
   try {
     obj = decoder.convert(objBuffer);
   } catch (Exception e) {
     LOG.error("Error occurred while trying to read object from buffer: {}", e);
   }
   return obj;
 }
Example #20
0
  @Override
  public void receiveCommand(String command, Side side, Object sender, ByteBuf stream) {
    super.receiveCommand(command, side, sender, stream);
    if (side.isClient()) {
      if ("clearItemRequirements".equals(command)) {
        requiredToBuild = null;
      } else if ("setItemRequirements".equals(command)) {
        int size = stream.readUnsignedMedium();
        requiredToBuild = new ArrayList<RequirementItemStack>();
        for (int i = 0; i < size; i++) {
          int itemId = stream.readUnsignedShort();
          int itemDamage = stream.readShort();
          int stackSize = stream.readUnsignedMedium();
          boolean hasCompound = stackSize >= 0x800000;

          ItemStack stack = new ItemStack(Item.getItemById(itemId), 1, itemDamage);
          if (hasCompound) {
            stack.setTagCompound(NetworkUtils.readNBT(stream));
          }

          if (stack != null && stack.getItem() != null) {
            requiredToBuild.add(new RequirementItemStack(stack, stackSize & 0x7FFFFF));
          } else {
            BCLog.logger.error(
                "Corrupt ItemStack in TileBuilder.receiveCommand! This should not happen! (ID "
                    + itemId
                    + ", damage "
                    + itemDamage
                    + ")");
          }
        }
      }
    } else if (side.isServer()) {
      EntityPlayer player = (EntityPlayer) sender;
      if ("eraseFluidTank".equals(command)) {
        int id = stream.readInt();
        if (id < 0 || id >= fluidTanks.length) {
          return;
        }
        if (isUseableByPlayer(player) && player.getDistanceSq(xCoord, yCoord, zCoord) <= 64) {
          fluidTanks[id].setFluid(null);
          sendNetworkUpdate();
        }
      }
    }
  }
 private void readAltSvcFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   long maxAge = payload.readUnsignedInt();
   int port = payload.readUnsignedShort();
   payload.skipBytes(1);
   short protocolIdLength = payload.readUnsignedByte();
   ByteBuf protocolId = payload.readSlice(protocolIdLength);
   short hostLength = payload.readUnsignedByte();
   String host = payload.toString(payload.readerIndex(), hostLength, UTF_8);
   payload.skipBytes(hostLength);
   String origin = null;
   if (payload.isReadable()) {
     origin = payload.toString(UTF_8);
     payload.skipBytes(payload.readableBytes());
   }
   observer.onAltSvcRead(ctx, streamId, maxAge, port, protocolId, host, origin);
 }
 @Override
 public SubobjectContainer parseSubobject(final ByteBuf buffer) throws RSVPParsingException {
   Preconditions.checkArgument(
       buffer != null && buffer.isReadable(),
       "Array of bytes is mandatory. Can't be null or empty.");
   if (buffer.readableBytes() != CONTENT_LENGTH) {
     throw new RSVPParsingException(
         "Wrong length of array of bytes. Passed: "
             + buffer.readableBytes()
             + "; Expected: >"
             + CONTENT_LENGTH
             + ".");
   }
   final int pathKey = buffer.readUnsignedShort();
   final byte[] pceId = ByteArray.readBytes(buffer, PCE_ID_F_LENGTH);
   final SubobjectContainerBuilder builder = new SubobjectContainerBuilder();
   final PathKeyBuilder pBuilder = new PathKeyBuilder();
   pBuilder.setPceId(new PceId(pceId));
   pBuilder.setPathKey(new PathKey(pathKey));
   builder.setSubobjectType(new PathKeyCaseBuilder().setPathKey(pBuilder.build()).build());
   return builder.build();
 }
 @Override
 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
   int available = in.readableBytes();
   if (available == 0) {
     return;
   }
   do {
     if (packetType == -1 && available >= 1) {
       packetType = in.readByte() - cipher.nextInt() & 0xff;
       packetSize = protocol.getInboundPacketSize(packetType);
       available--;
     }
     if (packetSize == -1) {
       if (available >= 1) {
         packetSize = in.readUnsignedByte();
         available--;
       } else {
         return;
       }
     } else if (packetSize == -2) {
       if (available >= 2) {
         packetSize = in.readUnsignedShort();
         available -= 2;
       } else {
         return;
       }
     }
     if (available < packetSize) {
       return;
     }
     byte[] data = new byte[packetSize];
     in.readBytes(data);
     out.add(new GamePacket(packetType, data));
     available -= packetSize;
     packetType = -1;
   } while (available > 0);
 }
 @Override
 protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
   if (result == null) {
     ByteBuf frame = (ByteBuf) super.decode(ctx, buffer);
     if (frame == null) {
       return null;
     }
     CompactObjectInputStream cois =
         new CompactObjectInputStream(new ByteBufInputStream(frame), classLoader);
     result = cois.readObject();
     streams = ExternalizeUtil.readList(cois, StreamFactoryReference.class);
     streamIndex = 0;
   }
   while (streamIndex < streams.size()) {
     // read the new chunk size
     if (streamDataToRead == -1) {
       if (buffer.readableBytes() < 2) {
         return null;
       }
       streamDataToRead = buffer.readUnsignedShort();
     }
     if (stream == null) {
       store = storageManager.createFileStore("temp-stream"); // $NON-NLS-1$
       StreamFactoryReference sfr = streams.get(streamIndex);
       sfr.setStreamFactory(new FileStoreInputStreamFactory(store, Streamable.ENCODING));
       this.stream = new BufferedOutputStream(store.createOutputStream());
     }
     // end of stream
     if (streamDataToRead == 0) {
       stream.close();
       stream = null;
       streamIndex++;
       streamDataToRead = -1;
       continue;
     }
     if (store.getLength() + streamDataToRead > maxLobSize) {
       if (error == null) {
         error =
             new StreamCorruptedException(
                 "lob too big: "
                     + (store.getLength() + streamDataToRead)
                     + " (max: "
                     + maxLobSize
                     + ')'); //$NON-NLS-1$ //$NON-NLS-2$
       }
     }
     if (error == null) {
       int toRead = Math.min(buffer.readableBytes(), streamDataToRead);
       if (toRead == 0) {
         return null;
       }
       buffer.readBytes(this.stream, toRead);
       streamDataToRead -= toRead;
       if (streamDataToRead == 0) {
         // get the next chunk
         streamDataToRead = -1;
       }
     } else {
       buffer.release();
       streamDataToRead = -1;
       break;
     }
   }
   Object toReturn = result;
   result = null;
   streams = null;
   stream = null;
   store = null;
   if (error != null) {
     StreamCorruptedException sce = error;
     error = null;
     throw sce;
   }
   return toReturn;
 }
 @Override
 public ExtendedCommunities parseExtendedCommunity(
     final ReferenceCache refCache, final ExtendedCommunitiesBuilder comm, final ByteBuf buffer)
     throws BGPDocumentedException {
   ExtendedCommunity c = null;
   if (comm.getCommType().equals(FS_TYPE)) {
     switch (comm.getCommSubType()) {
       case TRAFFIC_RATE_SUBTYPE:
         final ShortAsNumber as = new ShortAsNumber((long) buffer.readUnsignedShort());
         final Bandwidth value = new Bandwidth(ByteArray.readBytes(buffer, TRAFFIC_RATE_SIZE));
         c =
             new TrafficRateExtendedCommunityCaseBuilder()
                 .setTrafficRateExtendedCommunity(
                     new TrafficRateExtendedCommunityBuilder()
                         .setInformativeAs(as)
                         .setLocalAdministrator(value)
                         .build())
                 .build();
         break;
       case TRAFFIC_ACTION_SUBTYPE:
         buffer.skipBytes(RESERVED);
         final BitArray flags = BitArray.valueOf(buffer, FLAGS_SIZE);
         final boolean sample = flags.get(SAMPLE_BIT);
         final boolean terminal = flags.get(TERMINAL_BIT);
         c =
             new TrafficActionExtendedCommunityCaseBuilder()
                 .setTrafficActionExtendedCommunity(
                     new TrafficActionExtendedCommunityBuilder()
                         .setSample(sample)
                         .setTerminalAction(terminal)
                         .build())
                 .build();
         break;
       case REDIRECT_SUBTYPE:
         final ShortAsNumber as1 = new ShortAsNumber((long) buffer.readUnsignedShort());
         final byte[] byteValue = ByteArray.readBytes(buffer, TRAFFIC_RATE_SIZE);
         c =
             new RedirectExtendedCommunityCaseBuilder()
                 .setRedirectExtendedCommunity(
                     new RedirectExtendedCommunityBuilder()
                         .setGlobalAdministrator(as1)
                         .setLocalAdministrator(byteValue)
                         .build())
                 .build();
         break;
       case TRAFFIC_MARKING_SUBTYPE:
         buffer.skipBytes(RESERVED);
         final Dscp dscp = new Dscp(buffer.readUnsignedByte());
         c =
             new TrafficMarkingExtendedCommunityCaseBuilder()
                 .setTrafficMarkingExtendedCommunity(
                     new TrafficMarkingExtendedCommunityBuilder()
                         .setGlobalAdministrator(dscp)
                         .build())
                 .build();
         break;
       default:
         throw new BGPDocumentedException(
             "Could not parse Flowspec Extended Community type: " + comm.getCommSubType(),
             BGPError.OPT_ATTR_ERROR);
     }
   }
   if (c == null) {
     LOG.debug("Extended community is not from Flowspec, fallback to original communities.");
     return super.parseExtendedCommunity(refCache, comm, buffer);
   }
   return comm.setExtendedCommunity(c).build();
 }
  @Override
  public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {

    // Discard all data received if closing handshake was received before.
    if (receivedClosingHandshake) {
      in.skipBytes(actualReadableBytes());
      return null;
    }

    switch (state()) {
      case FRAME_START:
        framePayloadBytesRead = 0;
        framePayloadLength = -1;
        framePayload = null;

        // FIN, RSV, OPCODE
        byte b = in.readByte();
        frameFinalFlag = (b & 0x80) != 0;
        frameRsv = (b & 0x70) >> 4;
        frameOpcode = b & 0x0F;

        if (logger.isDebugEnabled()) {
          logger.debug("Decoding WebSocket Frame opCode={}", frameOpcode);
        }

        // MASK, PAYLOAD LEN 1
        b = in.readByte();
        boolean frameMasked = (b & 0x80) != 0;
        int framePayloadLen1 = b & 0x7F;

        if (frameRsv != 0 && !allowExtensions) {
          protocolViolation(ctx, "RSV != 0 and no extension negotiated, RSV:" + frameRsv);
          return null;
        }

        if (maskedPayload && !frameMasked) {
          protocolViolation(ctx, "unmasked client to server frame");
          return null;
        }
        if (frameOpcode > 7) { // control frame (have MSB in opcode set)

          // control frames MUST NOT be fragmented
          if (!frameFinalFlag) {
            protocolViolation(ctx, "fragmented control frame");
            return null;
          }

          // control frames MUST have payload 125 octets or less
          if (framePayloadLen1 > 125) {
            protocolViolation(ctx, "control frame with payload length > 125 octets");
            return null;
          }

          // check for reserved control frame opcodes
          if (!(frameOpcode == OPCODE_CLOSE
              || frameOpcode == OPCODE_PING
              || frameOpcode == OPCODE_PONG)) {
            protocolViolation(ctx, "control frame using reserved opcode " + frameOpcode);
            return null;
          }

          // close frame : if there is a body, the first two bytes of the
          // body MUST be a 2-byte unsigned integer (in network byte
          // order) representing a getStatus code
          if (frameOpcode == 8 && framePayloadLen1 == 1) {
            protocolViolation(ctx, "received close control frame with payload len 1");
            return null;
          }
        } else { // data frame
          // check for reserved data frame opcodes
          if (!(frameOpcode == OPCODE_CONT
              || frameOpcode == OPCODE_TEXT
              || frameOpcode == OPCODE_BINARY)) {
            protocolViolation(ctx, "data frame using reserved opcode " + frameOpcode);
            return null;
          }

          // check opcode vs message fragmentation state 1/2
          if (fragmentedFramesCount == 0 && frameOpcode == OPCODE_CONT) {
            protocolViolation(ctx, "received continuation data frame outside fragmented message");
            return null;
          }

          // check opcode vs message fragmentation state 2/2
          if (fragmentedFramesCount != 0
              && frameOpcode != OPCODE_CONT
              && frameOpcode != OPCODE_PING) {
            protocolViolation(
                ctx, "received non-continuation data frame while inside fragmented message");
            return null;
          }
        }

        // Read frame payload length
        if (framePayloadLen1 == 126) {
          framePayloadLength = in.readUnsignedShort();
          if (framePayloadLength < 126) {
            protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)");
            return null;
          }
        } else if (framePayloadLen1 == 127) {
          framePayloadLength = in.readLong();
          // TODO: check if it's bigger than 0x7FFFFFFFFFFFFFFF, Maybe
          // just check if it's negative?

          if (framePayloadLength < 65536) {
            protocolViolation(ctx, "invalid data frame length (not using minimal length encoding)");
            return null;
          }
        } else {
          framePayloadLength = framePayloadLen1;
        }

        if (framePayloadLength > maxFramePayloadLength) {
          protocolViolation(
              ctx, "Max frame length of " + maxFramePayloadLength + " has been exceeded.");
          return null;
        }

        if (logger.isDebugEnabled()) {
          logger.debug("Decoding WebSocket Frame length={}", framePayloadLength);
        }

        checkpoint(State.MASKING_KEY);
      case MASKING_KEY:
        if (maskedPayload) {
          maskingKey = in.readBytes(4);
        }
        checkpoint(State.PAYLOAD);
      case PAYLOAD:
        // Sometimes, the payload may not be delivered in 1 nice packet
        // We need to accumulate the data until we have it all
        int rbytes = actualReadableBytes();
        ByteBuf payloadBuffer = null;

        long willHaveReadByteCount = framePayloadBytesRead + rbytes;
        // logger.debug("Frame rbytes=" + rbytes + " willHaveReadByteCount="
        // + willHaveReadByteCount + " framePayloadLength=" +
        // framePayloadLength);
        if (willHaveReadByteCount == framePayloadLength) {
          // We have all our content so proceed to process
          payloadBuffer = ctx.alloc().buffer(rbytes);
          payloadBuffer.writeBytes(in, rbytes);
        } else if (willHaveReadByteCount < framePayloadLength) {

          // We don't have all our content so accumulate payload.
          // Returning null means we will get called back
          if (framePayload == null) {
            framePayload = ctx.alloc().buffer(toFrameLength(framePayloadLength));
          }
          framePayload.writeBytes(in, rbytes);
          framePayloadBytesRead += rbytes;

          // Return null to wait for more bytes to arrive
          return null;
        } else if (willHaveReadByteCount > framePayloadLength) {
          // We have more than what we need so read up to the end of frame
          // Leave the remainder in the buffer for next frame
          if (framePayload == null) {
            framePayload = ctx.alloc().buffer(toFrameLength(framePayloadLength));
          }
          framePayload.writeBytes(in, toFrameLength(framePayloadLength - framePayloadBytesRead));
        }

        // Now we have all the data, the next checkpoint must be the next
        // frame
        checkpoint(State.FRAME_START);

        // Take the data that we have in this packet
        if (framePayload == null) {
          framePayload = payloadBuffer;
        } else if (payloadBuffer != null) {
          framePayload.writeBytes(payloadBuffer);
        }

        // Unmask data if needed
        if (maskedPayload) {
          unmask(framePayload);
        }

        // Processing ping/pong/close frames because they cannot be
        // fragmented
        if (frameOpcode == OPCODE_PING) {
          return new PingWebSocketFrame(frameFinalFlag, frameRsv, framePayload);
        }
        if (frameOpcode == OPCODE_PONG) {
          return new PongWebSocketFrame(frameFinalFlag, frameRsv, framePayload);
        }
        if (frameOpcode == OPCODE_CLOSE) {
          checkCloseFrameBody(ctx, framePayload);
          receivedClosingHandshake = true;
          return new CloseWebSocketFrame(frameFinalFlag, frameRsv, framePayload);
        }

        // Processing for possible fragmented messages for text and binary
        // frames
        String aggregatedText = null;
        if (frameFinalFlag) {
          // Final frame of the sequence. Apparently ping frames are
          // allowed in the middle of a fragmented message
          if (frameOpcode != OPCODE_PING) {
            fragmentedFramesCount = 0;

            // Check text for UTF8 correctness
            if (frameOpcode == OPCODE_TEXT || fragmentedFramesText != null) {
              // Check UTF-8 correctness for this payload
              checkUTF8String(ctx, framePayload);

              // This does a second check to make sure UTF-8
              // correctness for entire text message
              aggregatedText = fragmentedFramesText.toString();

              fragmentedFramesText = null;
            }
          }
        } else {
          // Not final frame so we can expect more frames in the
          // fragmented sequence
          if (fragmentedFramesCount == 0) {
            // First text or binary frame for a fragmented set
            fragmentedFramesText = null;
            if (frameOpcode == OPCODE_TEXT) {
              checkUTF8String(ctx, framePayload);
            }
          } else {
            // Subsequent frames - only check if init frame is text
            if (fragmentedFramesText != null) {
              checkUTF8String(ctx, framePayload);
            }
          }

          // Increment counter
          fragmentedFramesCount++;
        }

        // Return the frame
        if (frameOpcode == OPCODE_TEXT) {
          return new TextWebSocketFrame(frameFinalFlag, frameRsv, framePayload);
        } else if (frameOpcode == OPCODE_BINARY) {
          return new BinaryWebSocketFrame(frameFinalFlag, frameRsv, framePayload);
        } else if (frameOpcode == OPCODE_CONT) {
          return new ContinuationWebSocketFrame(
              frameFinalFlag, frameRsv, framePayload, aggregatedText);
        } else {
          throw new UnsupportedOperationException(
              "Cannot decode web socket frame with opcode: " + frameOpcode);
        }
      case CORRUPT:
        // If we don't keep reading Netty will throw an exception saying
        // we can't return null if no bytes read and state not changed.
        in.readByte();
        return null;
      default:
        throw new Error("Shouldn't reach here.");
    }
  }
 @Override
 Integer read(ByteBuf buf) {
   return buf.readUnsignedShort();
 }
 @Override
 public int readUInt16() {
   return buf.readUnsignedShort();
 }
 @Override
 public int readUnsignedShort() {
   return buffer.readUnsignedShort();
 }
 @Override
 public void channelRead(final ChannelHandlerContext ctx, final Object inputObj) throws Exception {
   try {
     final ByteBuf input = (ByteBuf) inputObj;
     if (!input.isReadable()) {
       return;
     }
     final Channel channel = ctx.channel();
     receivedData.writeBytes(input);
     ProtocolVersion handshakeversion = ProtocolVersion.NOT_SET;
     receivedData.readerIndex(0);
     int firstbyte = receivedData.readUnsignedByte();
     switch (firstbyte) {
       case 0xFE:
         { // old ping
           try {
             if (receivedData.readableBytes() == 0) { // really old protocol probably
               scheduleTask(ctx, new Ping11ResponseTask(channel), 1000, TimeUnit.MILLISECONDS);
             } else if (receivedData.readUnsignedByte() == 1) {
               if (receivedData.readableBytes() == 0) {
                 // 1.5.2 probably
                 scheduleTask(
                     ctx, new Ping152ResponseTask(this, channel), 500, TimeUnit.MILLISECONDS);
               } else if ((receivedData.readUnsignedByte() == 0xFA)
                   && "MC|PingHost"
                       .equals(
                           new String(
                               Utils.toArray(
                                   receivedData.readBytes(receivedData.readUnsignedShort() * 2)),
                               StandardCharsets.UTF_16BE))) { // 1.6.*
                 receivedData.readUnsignedShort();
                 handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte());
               }
             }
           } catch (IndexOutOfBoundsException ex) {
           }
           break;
         }
       case 0x02:
         { // 1.6 or 1.5.2 handshake
           try {
             handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte());
           } catch (IndexOutOfBoundsException ex) {
           }
           break;
         }
       default:
         { // 1.7 or 1.8 handshake
           receivedData.readerIndex(0);
           ByteBuf data = getVarIntPrefixedData(receivedData);
           if (data != null) {
             handshakeversion = readNPHandshake(data);
           }
           break;
         }
     }
     // if we detected the protocol than we save it and process data
     if (handshakeversion != ProtocolVersion.NOT_SET) {
       setProtocol(channel, receivedData, handshakeversion);
     }
   } catch (Throwable t) {
     ctx.channel().close();
   } finally {
     ReferenceCountUtil.release(inputObj);
   }
 }