CoapDecoder implements StatelessProtocolDecoder<ByteBuffer, CoapMessage> { @Override public CoapMessage decode(ByteBuffer input, Void context) { LOG.debug("decode"); if (input.remaining() <= 0) { LOG.debug("nothing to decode"); return null; } int byte0 = input.get() & 0xFF; int version = (byte0 >> 6) & 0x3; MessageType type = MessageType.fromCode((byte0 >> 4) & 0x3); byte[] token = new byte[byte0 & 0xF]; int code = input.get() & 0xFF; int id = input.getShort() & 0xFFFF; input.get(token); int optionCode = 0; byte[] payload = EMPTY_PAYLOAD; List<CoapOption> options = new ArrayList<CoapOption>(); while (input.hasRemaining()) { int next = input.get() & 0xFF; if (next == 0xFF) { payload = new byte[input.remaining()]; input.get(payload); break; } else { int optionDeltaQuartet = (next >> 4) & 0xF; optionCode += optionFromQuartet(optionDeltaQuartet, input); int optionLenQuartet = next & 0x0F; int optionLength = optionFromQuartet(optionLenQuartet, input); CoapOptionType optType = CoapOptionType.fromCode(optionCode); if (optType == null) { throw new ProtocolDecoderException("unknown option code : " + optionCode); } byte[] optionValue = new byte[optionLength]; input.get(optionValue); options.add(new CoapOption(optType, optionValue)); } } if (input.hasRemaining()) { throw new ProtocolDecoderException("trailling " + input.remaining() + " bytes in the UDP datagram"); } return new CoapMessage(version, type, code, id, token, options.toArray(EMPTY_OPTION), payload); }  @Override Void createDecoderState(); @Override CoapMessage decode(ByteBuffer input, Void context); @Override void finishDecode(Void context);  }
@Test public void some_content_no_option() { Assert.assertEquals(SOME_CONTENT_NO_OPTION, decoder.decode(ByteBufferDumper.fromHexString(SOME_CONTENT_NO_OPTION_HEX), null)); }
@Test public void no_content_no_option() { Assert.assertEquals(NO_CONTENT_NO_OPTION, decoder.decode(ByteBufferDumper.fromHexString(NO_CONTENT_NO_OPTION_HEX), null)); }
@Test public void payload_and_one_option() { Assert.assertEquals(PAYLOAD_AND_ONE_OPTION, decoder.decode(ByteBufferDumper.fromHexString(PAYLOAD_AND_ONE_OPTION_HEX), null)); }
@Test public void payload_and_multiple_option() { Assert.assertEquals(PAYLOAD_AND_MULTIPLE_OPTION, decoder.decode(ByteBufferDumper.fromHexString(PAYLOAD_AND_MULTIPLE_OPTION_HEX), null)); }
@Test public void observe_message() { Assert.assertEquals(OBSERVE, decoder.decode(ByteBufferDumper.fromHexString(OBSERVE_HEX), null)); }