org.apache.qpid.proton.codec.DecoderImpl Java Examples

The following examples show how to use org.apache.qpid.proton.codec.DecoderImpl. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AMQPLargeMessage.java    From activemq-artemis with Apache License 2.0 6 votes vote down vote up
public void parseHeader(ReadableBuffer buffer) {

      DecoderImpl decoder = TLSEncode.getDecoder();
      decoder.setBuffer(buffer);

      try {
         int constructorPos = buffer.position();
         TypeConstructor<?> constructor = decoder.readConstructor();
         if (Header.class.equals(constructor.getTypeClass())) {
            header = (Header) constructor.readValue();
            if (header.getTtl() != null) {
               expiration = System.currentTimeMillis() + header.getTtl().intValue();
            }
         }
      } finally {
         decoder.setBuffer(null);
         buffer.rewind();
      }
   }
 
Example #2
Source File: CoreAmqpConverter.java    From activemq-artemis with Apache License 2.0 6 votes vote down vote up
private static Object decodeEmbeddedAMQPType(Object payload) {
   final byte[] encodedType = (byte[]) payload;

   final DecoderImpl decoder = TLSEncode.getDecoder();
   Object decodedType = null;

   decoder.setBuffer(ByteBufferReader.wrap(encodedType));

   try {
      decodedType = decoder.readObject();
   } finally {
      decoder.setBuffer(null);
   }

   return decodedType;
}
 
Example #3
Source File: FrameWriterBenchmark.java    From qpid-proton-j with Apache License 2.0 6 votes vote down vote up
public void initProton() {
    byteBuf = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
    this.decoder = new DecoderImpl();
    this.encoder = new EncoderImpl(decoder);
    AMQPDefinedTypes.registerAllTypes(decoder, encoder);

    transport = (TransportImpl) Proton.transport();
    frameWriter = new FrameWriter(encoder, 16 * 1024, (byte) 0, transport);

    transfer = new Transfer();
    transfer.setDeliveryId(UnsignedInteger.ONE);
    transfer.setHandle(UnsignedInteger.valueOf(16));
    transfer.setDeliveryTag(new Binary(new byte[] { 0, 1}));
    transfer.setMessageFormat(UnsignedInteger.ZERO);

    payload = ReadableBuffer.ByteBufferReader.wrap(PAYLOAD_BYTES);
}
 
Example #4
Source File: FastPathAcceptedType.java    From qpid-proton-j with Apache License 2.0 6 votes vote down vote up
@Override
public Accepted readValue() {
    DecoderImpl decoder = getDecoder();
    byte typeCode = decoder.getBuffer().get();

    switch (typeCode) {
        case EncodingCodes.LIST0:
            break;
        case EncodingCodes.LIST8:
            decoder.getBuffer().get();
            decoder.getBuffer().get();
            break;
        case EncodingCodes.LIST32:
            decoder.getBuffer().getInt();
            decoder.getBuffer().getInt();
            break;
        default:
            throw new DecodeException("Incorrect type found in Accepted type encoding: " + typeCode);
    }

    return Accepted.getInstance();
}
 
Example #5
Source File: FastPathApplicationPropertiesType.java    From qpid-proton-j with Apache License 2.0 6 votes vote down vote up
private static TypeConstructor<?> findNextDecoder(DecoderImpl decoder, ReadableBuffer buffer, TypeConstructor<?> previousConstructor) {
    if (previousConstructor == null) {
        return decoder.readConstructor();
    } else {
        byte encodingCode = buffer.get(buffer.position());
        if (encodingCode == EncodingCodes.DESCRIBED_TYPE_INDICATOR || !(previousConstructor instanceof PrimitiveTypeEncoding<?>)) {
            previousConstructor = decoder.readConstructor();
        } else {
            PrimitiveTypeEncoding<?> primitiveConstructor = (PrimitiveTypeEncoding<?>) previousConstructor;
            if (encodingCode != primitiveConstructor.getEncodingCode()) {
                previousConstructor = decoder.readConstructor();
            } else {
                // consume the encoding code byte for real
                encodingCode = buffer.get();
            }
        }
    }

    if (previousConstructor == null) {
        throw new DecodeException("Unknown constructor found in Map encoding: ");
    }

    return previousConstructor;
}
 
Example #6
Source File: FastPathMessageAnnotationsType.java    From qpid-proton-j with Apache License 2.0 6 votes vote down vote up
private static TypeConstructor<?> findNextDecoder(DecoderImpl decoder, ReadableBuffer buffer, TypeConstructor<?> previousConstructor) {
    if (previousConstructor == null) {
        return decoder.readConstructor();
    } else {
        byte encodingCode = buffer.get(buffer.position());
        if (encodingCode == EncodingCodes.DESCRIBED_TYPE_INDICATOR || !(previousConstructor instanceof PrimitiveTypeEncoding<?>)) {
            previousConstructor = decoder.readConstructor();
        } else {
            PrimitiveTypeEncoding<?> primitiveConstructor = (PrimitiveTypeEncoding<?>) previousConstructor;
            if (encodingCode != primitiveConstructor.getEncodingCode()) {
                previousConstructor = decoder.readConstructor();
            } else {
                // consume the encoding code byte for real
                encodingCode = buffer.get();
            }
        }
    }

    if (previousConstructor == null) {
        throw new DecodeException("Unknown constructor found in Map encoding: ");
    }

    return previousConstructor;
}
 
Example #7
Source File: FastPathDeliveryAnnotationsType.java    From qpid-proton-j with Apache License 2.0 6 votes vote down vote up
private static TypeConstructor<?> findNextDecoder(DecoderImpl decoder, ReadableBuffer buffer, TypeConstructor<?> previousConstructor) {
    if (previousConstructor == null) {
        return decoder.readConstructor();
    } else {
        byte encodingCode = buffer.get(buffer.position());
        if (encodingCode == EncodingCodes.DESCRIBED_TYPE_INDICATOR || !(previousConstructor instanceof PrimitiveTypeEncoding<?>)) {
            previousConstructor = decoder.readConstructor();
        } else {
            PrimitiveTypeEncoding<?> primitiveConstructor = (PrimitiveTypeEncoding<?>) previousConstructor;
            if (encodingCode != primitiveConstructor.getEncodingCode()) {
                previousConstructor = decoder.readConstructor();
            } else {
                // consume the encoding code byte for real
                encodingCode = buffer.get();
            }
        }
    }

    if (previousConstructor == null) {
        throw new DecodeException("Unknown constructor found in Map encoding: ");
    }

    return previousConstructor;
}
 
Example #8
Source File: AmqpCodec.java    From qpid-jms with Apache License 2.0 5 votes vote down vote up
/**
 * Given an encoded AMQP Section, decode the value previously written there.
 *
 * @param encoded
 *      the AMQP Section value to decode.
 *
 * @return a Section object read from its encoded form.
 */
public static Section decode(ByteBuf encoded) {
    if (encoded == null || !encoded.isReadable()) {
        return null;
    }

    DecoderImpl decoder = TLS_CODEC.get().decoder;
    decoder.setByteBuffer(encoded.nioBuffer());
    Section result = (Section) decoder.readObject();
    decoder.setByteBuffer(null);
    encoded.resetReaderIndex();

    return result;
}
 
Example #9
Source File: AMQPMessageSymbolSearch.java    From activemq-artemis with Apache License 2.0 5 votes vote down vote up
private static boolean lookupOnSection(IdentityHashMap<Class<?>, Boolean> stopSet, final Class section, final ReadableBuffer data, final KMPNeedle[] needles, final int startAt) {
   DecoderImpl decoder = TLSEncode.getDecoder();
   final int position = data.position();
   decoder.setBuffer(data.position(startAt));
   try {
      while (data.hasRemaining()) {
         TypeConstructor<?> constructor = decoder.readConstructor();
         final Class<?> typeClass = constructor.getTypeClass();
         if (MSG_ANNOTATIONS_STOPSET.containsKey(typeClass)) {
            if (section.equals(typeClass)) {
               final int start = data.position();
               constructor.skipValue();
               final int end = data.position();
               for (int i = 0, count = needles.length; i < count; i++) {
                  final int foundIndex = needles[i].searchInto(data, start, end);
                  if (foundIndex != -1) {
                     return true;
                  }
               }
            }
            return false;
         }
         constructor.skipValue();
      }
      return false;
   } finally {
      decoder.setBuffer(null);
      data.position(position);
   }
}
 
Example #10
Source File: AMQPMessage.java    From activemq-artemis with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings({ "unchecked", "rawtypes" })
protected <T> T scanForMessageSection(int scanStartPosition, Class...targetTypes) {
   ensureMessageDataScanned();

   // In cases where we parsed out enough to know the value is not encoded in the message
   // we can exit without doing any reads or buffer hopping.
   if (scanStartPosition == VALUE_NOT_PRESENT) {
      return null;
   }

   ReadableBuffer buffer = getData().duplicate().position(0);
   final DecoderImpl decoder = TLSEncode.getDecoder();

   buffer.position(scanStartPosition);

   T section = null;

   decoder.setBuffer(buffer);
   try {
      while (buffer.hasRemaining()) {
         TypeConstructor<?> constructor = decoder.readConstructor();
         for (Class<?> type : targetTypes) {
            if (type.equals(constructor.getTypeClass())) {
               section = (T) constructor.readValue();
               return section;
            }
         }

         constructor.skipValue();
      }
   } finally {
      decoder.setBuffer(null);
   }

   return section;
}
 
Example #11
Source File: MessageBenchmark.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
public void init()
{
    byteBuf = ByteBuffer.allocate(bufferSize());
    this.decoder = new DecoderImpl();
    this.encoder = new EncoderImpl(decoder);
    AMQPDefinedTypes.registerAllTypes(decoder, encoder);
    //initialize encoders
    encoder.setByteBuffer(byteBuf);
    decoder.setByteBuffer(byteBuf);
}
 
Example #12
Source File: InteropTest.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
Decoder createDecoder(byte[] data)
{
    DecoderImpl decoder = new DecoderImpl();
    AMQPDefinedTypes.registerAllTypes(decoder, new EncoderImpl(decoder));
    ByteBuffer buffer = ByteBuffer.allocate(data.length);
    buffer.put(data);
    buffer.rewind();
    decoder.setByteBuffer(buffer);

    return decoder;
}
 
Example #13
Source File: SaslFrameParserTest.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
public SaslFrameParserTest()
{
    DecoderImpl decoder = new DecoderImpl();
    EncoderImpl encoder = new EncoderImpl(decoder);
    AMQPDefinedTypes.registerAllTypes(decoder,encoder);

    _frameParser = new SaslFrameParser(_mockSaslFrameHandler, decoder, Transport.MIN_MAX_FRAME_SIZE, mockTransport);
    _saslFrameBody = new SaslInit();
    _saslFrameBody.setMechanism(Symbol.getSymbol("unused"));
    _saslFrameBytes = ByteBuffer.wrap(_amqpFramer.generateSaslFrame(0, new byte[0], _saslFrameBody));
}
 
Example #14
Source File: FastPathTransferType.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
@Override
public Transfer readValue() {
    DecoderImpl decoder = getDecoder();
    byte typeCode = decoder.getBuffer().get();

    @SuppressWarnings("unused")
    int size = 0;
    int count = 0;

    switch (typeCode) {
        case EncodingCodes.LIST0:
            // TODO - Technically invalid however old decoder also allowed this.
            break;
        case EncodingCodes.LIST8:
            size = ((int)decoder.getBuffer().get()) & 0xff;
            count = ((int)decoder.getBuffer().get()) & 0xff;
            break;
        case EncodingCodes.LIST32:
            size = decoder.getBuffer().getInt();
            count = decoder.getBuffer().getInt();
            break;
        default:
            throw new DecodeException("Incorrect type found in Transfer encoding: " + typeCode);
    }

    if (count < 1) {
        throw new DecodeException("The handle field cannot be omitted");
    }

    try {
        return readFields(decoder, count);
    } catch (NullPointerException npe) {
        throw new DecodeException("Unexpected null value - mandatory field not set? (" + npe.getMessage() + ")", npe);
    }
}
 
Example #15
Source File: FastPathFlowType.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
@Override
public Flow readValue() {
    DecoderImpl decoder = getDecoder();
    byte typeCode = decoder.getBuffer().get();

    @SuppressWarnings("unused")
    int size = 0;
    int count = 0;

    switch (typeCode) {
        case EncodingCodes.LIST0:
            // TODO - Technically invalid however old decoder also allowed this.
            break;
        case EncodingCodes.LIST8:
            size = ((int)decoder.getBuffer().get()) & 0xff;
            count = ((int)decoder.getBuffer().get()) & 0xff;
            break;
        case EncodingCodes.LIST32:
            size = decoder.getBuffer().getInt();
            count = decoder.getBuffer().getInt();
            break;
        default:
            throw new DecodeException("Incorrect type found in Flow encoding: " + typeCode);
    }

    if (count < 4) {
        throw new DecodeException("The outgoing-window field cannot be omitted");
    }

    try {
        return readFields(decoder, count);
    } catch (NullPointerException npe) {
        throw new DecodeException("Unexpected null value - mandatory field not set? (" + npe.getMessage() + ")", npe);
    }
}
 
Example #16
Source File: FastPathDispositionType.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
@Override
public Disposition readValue() {
    DecoderImpl decoder = getDecoder();
    byte typeCode = decoder.getBuffer().get();

    @SuppressWarnings("unused")
    int size = 0;
    int count = 0;

    switch (typeCode) {
        case EncodingCodes.LIST0:
            // TODO - Technically invalid however old decoder also allowed this.
            break;
        case EncodingCodes.LIST8:
            size = ((int)decoder.getBuffer().get()) & 0xff;
            count = ((int)decoder.getBuffer().get()) & 0xff;
            break;
        case EncodingCodes.LIST32:
            size = decoder.getBuffer().getInt();
            count = decoder.getBuffer().getInt();
            break;
        default:
            throw new DecodeException("Incorrect type found in Disposition encoding: " + typeCode);
    }

    if (count < 2) {
        throw new DecodeException("The 'first' field cannot be omitted");
    }

    try {
        return readFields(decoder, count);
    } catch (NullPointerException npe) {
        throw new DecodeException("Unexpected null value - mandatory field not set? (" + npe.getMessage() + ")", npe);
    }
}
 
Example #17
Source File: FastPathDispositionType.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
private final Disposition readFields(DecoderImpl decoder, int count) {
    Disposition disposition = new Disposition();

    for (int index = 0; index < count; ++index) {
        switch (index) {
            case 0:
                disposition.setRole(Boolean.TRUE.equals(decoder.readBoolean()) ? Role.RECEIVER : Role.SENDER);
                break;
            case 1:
                disposition.setFirst(decoder.readUnsignedInteger(null));
                break;
            case 2:
                disposition.setLast(decoder.readUnsignedInteger(null));
                break;
            case 3:
                disposition.setSettled(decoder.readBoolean(false));
                break;
            case 4:
                disposition.setState((DeliveryState) decoder.readObject());
                break;
            case 5:
                disposition.setBatchable(decoder.readBoolean(false));
                break;
            default:
                throw new IllegalStateException("To many entries in Disposition encoding");
        }
    }

    return disposition;
}
 
Example #18
Source File: FastPathAcceptedType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public DecoderImpl getDecoder() {
    return acceptedType.getDecoder();
}
 
Example #19
Source File: FastPathTransferType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public DecoderImpl getDecoder() {
    return transferType.getDecoder();
}
 
Example #20
Source File: AmqpCodec.java    From qpid-jms with Apache License 2.0 4 votes vote down vote up
/**
 * @return a Decoder instance.
 */
public static DecoderImpl getDecoder() {
    return TLS_CODEC.get().decoder;
}
 
Example #21
Source File: TLSEncode.java    From activemq-artemis with Apache License 2.0 4 votes vote down vote up
public static DecoderImpl getDecoder() {
   return tlsCodec.get().decoder;
}
 
Example #22
Source File: FastPathTransferType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
private final Transfer readFields(DecoderImpl decoder, int count) {
    Transfer transfer = new Transfer();

    for (int index = 0; index < count; ++index) {
        switch (index) {
            case 0:
                transfer.setHandle(decoder.readUnsignedInteger(null));
                break;
            case 1:
                transfer.setDeliveryId(decoder.readUnsignedInteger(null));
                break;
            case 2:
                transfer.setDeliveryTag(decoder.readBinary(null));
                break;
            case 3:
                transfer.setMessageFormat(decoder.readUnsignedInteger(null));
                break;
            case 4:
                transfer.setSettled(decoder.readBoolean(null));
                break;
            case 5:
                transfer.setMore(decoder.readBoolean(false));
                break;
            case 6:
                UnsignedByte rcvSettleMode = decoder.readUnsignedByte();
                transfer.setRcvSettleMode(rcvSettleMode == null ? null : ReceiverSettleMode.values()[rcvSettleMode.intValue()]);
                break;
            case 7:
                transfer.setState((DeliveryState) decoder.readObject());
                break;
            case 8:
                transfer.setResume(decoder.readBoolean(false));
                break;
            case 9:
                transfer.setAborted(decoder.readBoolean(false));
                break;
            case 10:
                transfer.setBatchable(decoder.readBoolean(false));
                break;
            default:
                throw new IllegalStateException("To many entries in Transfer encoding");
        }
    }

    return transfer;
}
 
Example #23
Source File: AMQPMessage.java    From activemq-artemis with Apache License 2.0 4 votes vote down vote up
protected synchronized void scanMessageData() {
   this.messageDataScanned = MessageDataScanningStatus.SCANNED.code;
   DecoderImpl decoder = TLSEncode.getDecoder();
   decoder.setBuffer(getData().rewind());

   resetMessageData();

   ReadableBuffer data = getData();

   try {
      while (data.hasRemaining()) {
         int constructorPos = data.position();
         TypeConstructor<?> constructor = decoder.readConstructor();
         if (Header.class.equals(constructor.getTypeClass())) {
            header = (Header) constructor.readValue();
            headerPosition = constructorPos;
            encodedHeaderSize = data.position();
            if (header.getTtl() != null) {
               expiration = System.currentTimeMillis() + header.getTtl().intValue();
            }
         } else if (DeliveryAnnotations.class.equals(constructor.getTypeClass())) {
            // Don't decode these as they are not used by the broker at all and are
            // discarded on send, mark for lazy decode if ever needed.
            constructor.skipValue();
            deliveryAnnotationsPosition = constructorPos;
            encodedDeliveryAnnotationsSize = data.position() - constructorPos;
         } else if (MessageAnnotations.class.equals(constructor.getTypeClass())) {
            messageAnnotationsPosition = constructorPos;
            messageAnnotations = (MessageAnnotations) constructor.readValue();
         } else if (Properties.class.equals(constructor.getTypeClass())) {
            propertiesPosition = constructorPos;
            properties = (Properties) constructor.readValue();

            if (properties.getAbsoluteExpiryTime() != null && properties.getAbsoluteExpiryTime().getTime() > 0) {
               expiration = properties.getAbsoluteExpiryTime().getTime();
            }
         } else if (ApplicationProperties.class.equals(constructor.getTypeClass())) {
            // Lazy decoding will start at the TypeConstructor of these ApplicationProperties
            // but we scan past it to grab the location of the possible body and footer section.
            applicationPropertiesPosition = constructorPos;
            constructor.skipValue();
            remainingBodyPosition = data.hasRemaining() ? data.position() : VALUE_NOT_PRESENT;
            break;
         } else {
            // This will be either the body or a Footer section which will be treated as an immutable
            // and be copied as is when re-encoding the message.
            remainingBodyPosition = constructorPos;
            break;
         }
      }
   } finally {
      decoder.setByteBuffer(null);
      data.rewind();
   }
}
 
Example #24
Source File: FastPathFlowType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public DecoderImpl getDecoder() {
    return flowType.getDecoder();
}
 
Example #25
Source File: FastPathFlowType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
private final Flow readFields(DecoderImpl decoder, int count) {
    Flow flow = new Flow();

    for (int index = 0; index < count; ++index) {
        switch (index) {
            case 0:
                flow.setNextIncomingId(decoder.readUnsignedInteger(null));
                break;
            case 1:
                flow.setIncomingWindow(decoder.readUnsignedInteger(null));
                break;
            case 2:
                flow.setNextOutgoingId(decoder.readUnsignedInteger(null));
                break;
            case 3:
                flow.setOutgoingWindow(decoder.readUnsignedInteger(null));
                break;
            case 4:
                flow.setHandle(decoder.readUnsignedInteger(null));
                break;
            case 5:
                flow.setDeliveryCount(decoder.readUnsignedInteger(null));
                break;
            case 6:
                flow.setLinkCredit(decoder.readUnsignedInteger(null));
                break;
            case 7:
                flow.setAvailable(decoder.readUnsignedInteger(null));
                break;
            case 8:
                flow.setDrain(decoder.readBoolean(false));
                break;
            case 9:
                flow.setEcho(decoder.readBoolean(false));
                break;
            case 10:
                flow.setProperties(decoder.readMap());
                break;
            default:
                throw new IllegalStateException("To many entries in Flow encoding");
        }
    }

    return flow;
}
 
Example #26
Source File: FastPathDispositionType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public DecoderImpl getDecoder() {
    return dispositionType.getDecoder();
}
 
Example #27
Source File: FastPathPropertiesType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public DecoderImpl getDecoder() {
    return propertiesType.getDecoder();
}
 
Example #28
Source File: FastPathDeliveryAnnotationsType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
@Override
public DeliveryAnnotations readValue() {
    DecoderImpl decoder = getDecoder();
    ReadableBuffer buffer = decoder.getBuffer();

    final int size;
    final int count;

    byte encodingCode = buffer.get();

    switch (encodingCode) {
        case EncodingCodes.MAP8:
            size = buffer.get() & 0xFF;
            count = buffer.get() & 0xFF;
            break;
        case EncodingCodes.MAP32:
            size = buffer.getInt();
            count = buffer.getInt();
            break;
        case EncodingCodes.NULL:
            return new DeliveryAnnotations(null);
        default:
            throw new ProtonException("Expected Map type but found encoding: " + encodingCode);
    }

    if (count > buffer.remaining()) {
        throw new IllegalArgumentException("Map element count " + count + " is specified to be greater than the " +
                                           "amount of data available (" + buffer.remaining() + ")");
    }

    TypeConstructor<?> valueConstructor = null;

    Map<Symbol, Object> map = new LinkedHashMap<>(count);
    for(int i = 0; i < count / 2; i++) {
        Symbol key = decoder.readSymbol(null);
        if (key == null) {
            throw new DecodeException("String key in DeliveryAnnotations cannot be null");
        }

        boolean arrayType = false;
        byte code = buffer.get(buffer.position());
        switch (code)
        {
            case EncodingCodes.ARRAY8:
            case EncodingCodes.ARRAY32:
                arrayType = true;
        }

        valueConstructor = findNextDecoder(decoder, buffer, valueConstructor);

        final Object value;

        if (arrayType) {
            value = ((ArrayType.ArrayEncoding) valueConstructor).readValueArray();
        } else {
            value = valueConstructor.readValue();
        }

        map.put(key, value);
    }

    return new DeliveryAnnotations(map);
}
 
Example #29
Source File: FastPathAmqpSequenceType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public DecoderImpl getDecoder() {
    return sequenceType.getDecoder();
}
 
Example #30
Source File: FastPathPropertiesType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
@Override
public Properties readValue() {
    DecoderImpl decoder = getDecoder();
    ReadableBuffer buffer = decoder.getBuffer();
    byte typeCode = decoder.getBuffer().get();

    @SuppressWarnings("unused")
    int size = 0;
    int count = 0;

    switch (typeCode) {
        case EncodingCodes.LIST0:
            break;
        case EncodingCodes.LIST8:
            size = buffer.get() & 0xff;
            count = buffer.get() & 0xff;
            break;
        case EncodingCodes.LIST32:
            size = buffer.getInt();
            count = buffer.getInt();
            break;
        default:
            throw new DecodeException("Incorrect type found in Properties encoding: " + typeCode);
    }

    Properties properties = new Properties();

    for (int index = 0; index < count; ++index) {
        switch (index) {
            case 0:
                properties.setMessageId(decoder.readObject());
                break;
            case 1:
                properties.setUserId(decoder.readBinary(null));
                break;
            case 2:
                properties.setTo(decoder.readString(null));
                break;
            case 3:
                properties.setSubject(decoder.readString(null));
                break;
            case 4:
                properties.setReplyTo(decoder.readString(null));
                break;
            case 5:
                properties.setCorrelationId(decoder.readObject());
                break;
            case 6:
                properties.setContentType(decoder.readSymbol(null));
                break;
            case 7:
                properties.setContentEncoding(decoder.readSymbol(null));
                break;
            case 8:
                properties.setAbsoluteExpiryTime(decoder.readTimestamp(null));
                break;
            case 9:
                properties.setCreationTime(decoder.readTimestamp(null));
                break;
            case 10:
                properties.setGroupId(decoder.readString(null));
                break;
            case 11:
                properties.setGroupSequence(decoder.readUnsignedInteger(null));
                break;
            case 12:
                properties.setReplyToGroupId(decoder.readString(null));
                break;
            default:
                throw new IllegalStateException("To many entries in Properties encoding");
        }
    }

    return properties;
}