private static int tlvEncodedLength(Tlv tlv) { int length; switch (tlv.getType()) { case RESOURCE_VALUE: case RESOURCE_INSTANCE: length = tlv.getValue().length; break; default: length = 0; for (Tlv child : tlv.getChildren()) { int subLength = tlvEncodedLength(child); length += tlvEncodedSize(child, subLength); } } return length; }
private static void encode(Tlv tlv, ByteBuffer b) { int length; length = tlvEncodedLength(tlv); int typeByte; switch (tlv.getType()) { case OBJECT_INSTANCE: typeByte = 0b00_000000; break; case RESOURCE_INSTANCE: typeByte = 0b01_000000; break; case MULTIPLE_RESOURCE: typeByte = 0b10_000000; break; case RESOURCE_VALUE: // encode the value typeByte = 0b11_000000; break; default: throw new IllegalArgumentException("unknown TLV type : '" + tlv.getType() + "'"); } // encode identifier length typeByte |= (tlv.getIdentifier() < MAX_LENGTH_8BIT) ? 0b00_0000 : 0b10_0000; // type of length if (length < 8) { typeByte |= length; } else if (length < MAX_LENGTH_8BIT) { typeByte |= 0b0000_1000; } else if (length < MAX_LENGTH_16BIT) { typeByte |= 0b0001_0000; } else { typeByte |= 0b0001_1000; } // fill the buffer b.put((byte) typeByte); if (tlv.getIdentifier() < MAX_LENGTH_8BIT) { b.put((byte) tlv.getIdentifier()); } else { b.putShort((short) tlv.getIdentifier()); } // write length if (length >= 8) { if (length < MAX_LENGTH_8BIT) { b.put((byte) length); } else if (length < MAX_LENGTH_16BIT) { b.putShort((short) length); } else { int msb = (length & 0xFF_00_00) >> 16; b.put((byte) msb); b.putShort((short) (length & 0xFF_FF)); typeByte |= 0b0001_1000; } } switch (tlv.getType()) { case RESOURCE_VALUE: case RESOURCE_INSTANCE: b.put(tlv.getValue()); break; default: for (Tlv child : tlv.getChildren()) { encode(child, b); } break; } }